您的位置:首页 > 移动开发 > Unity3D

Unity编辑器扩展:导表工具(3)(通用版)

2019-06-13 18:24 2166 查看

以下均为我个人总结的方案,如果有所不足的地方,请多多包涵

有更好的方案或者有错误之处,敬请留言,谢谢您看了我的博客

三:导出数据

此工具支持导出什么语言,区别就在这层,之前的两个步骤,与此步骤都不相关。

简单的说,需要导出的格式就在这里写,lua,java,二进制等等。

目前我将excel数据导出的格式为ScriptableObject,.asset资源文件。

ScriptableObject就是“脚本化对象”,将这类作为存储结构化的数据来使用,并写入Unity的资源.asset文件去存储一组数据,取用的时候直接作为一个数据对象拿来用。

无论我们是创建或读取.asset资源,都需要一个与.asset文件格式对应的scripttableobject类。

所以,我利用步骤二已知数据,导出一个与excel表相对应的ScriptableObject类,然后通过反射,再使用此类导出.asset资源文件。

当然导出的ScriptableObject类,为了与我项目内的数据管理模块相接,所以略微加入了一些方法。

代码写在步骤二中已经提到过的ExportExcelToClient函数中。

[code]            var u8WithoutBom = new System.Text.UTF8Encoding(false);

string csUpName = curFileName.ToUpper().Substring(0, 1) + curFileName.Substring(1);

if (exportType == EXPORT_TYPE_LUA)
{

}
if (exportType == EXPORT_TYPE_JSON)
{

}
if (exportType == EXPORT_TYPE_SCRIPT)
{
////以下为使用excel数据时候使用的C# scriptable脚本
string cPath;
StreamWriter cSw;
cPath = Application.dataPath + _clientEditorPath + "DataTable" + csUpName + ".cs";
if (System.IO.File.Exists(cPath))
{
File.Delete(cPath);
}
cSw = new StreamWriter(cPath, false, u8WithoutBom);
cSw.WriteLine("/*=====================================================");
cSw.WriteLine("* - Editor by tool");
cSw.WriteLine("* - Don't editor by handself");
cSw.WriteLine("=====================================================*/");
cSw.WriteLine("using System;");
cSw.WriteLine("using UnityEngine;");
cSw.WriteLine("using System.Collections.Generic;");
cSw.WriteLine("using Zero.ZeroEngine.Data;");
cSw.Write("\n");
cSw.Write("\n");
cSw.WriteLine("[System.Serializable]");
cSw.WriteLine("public class " + csUpName + "Excel {");
for (int i = 0; i < index.Count; i++)//循环所有的列数
{
cSw.Write("\tpublic ");
if (dicClientTypes[index[i]] == "string")
{
cSw.Write("string ");
}
else if (dicClientTypes[index[i]] == "int")
{
cSw.Write("int ");
}
else if (dicClientTypes[index[i]] == "array")
{
cSw.Write("int[] ");
}
cSw.Write(dicClientMembers[index[i]] + ";\n");
}
cSw.Write("}\n");
cSw.WriteLine("public class DataTable" + csUpName + ": DataBase {");
cSw.WriteLine("\t[SerializeField]");
cSw.WriteLine("\tpublic List<" + csUpName + "Excel> DataList = new List<" + csUpName + "Excel>();\r");

if (keyNum == 1)
{
cSw.WriteLine("\tprivate Dictionary<" + dicClientTypes[index[0]] + ", " + csUpName +
"Excel> _dataList = new Dictionary<" + dicClientTypes[index[0]] + ", " + csUpName +
"Excel>();");
}
else if (keyNum == 2)
{
cSw.WriteLine("\tprivate Dictionary<" + dicClientTypes[index[0]] + ", Dictionary<" + dicClientTypes[index[1]] + ", " + csUpName +
"Excel>> _dataList = new Dictionary<" + dicClientTypes[index[0]] + ", Dictionary<" + dicClientTypes[index[1]] + ", " + csUpName +
"Excel>>();");
}
else if(keyNum == 3)
{

}

cSw.WriteLine("\tpublic void AddInfo(" + csUpName + "Excel _info)");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tDataList.Add(_info);");
cSw.WriteLine("\t}");

if (keyNum == 1)
{
cSw.WriteLine("\tpublic override void Init()");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tforeach (var info in DataList)");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\t_dataList.Add(info." + dicClientMembers[0] + ", info);");
cSw.WriteLine("\t\t}");
cSw.WriteLine("\t}");//区分

cSw.WriteLine("\tpublic Dictionary<" + dicClientTypes[index[0]] + ", " + csUpName + "Excel> GetInfo()");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\treturn _dataList;");
cSw.WriteLine("\t}");//区分

cSw.WriteLine("\tpublic " + csUpName + "Excel GetInfoById(" + dicClientTypes[index[0]] + " _id)");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tvar info = _dataList[_id];");
cSw.WriteLine("\t\tif (info != null)");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\treturn info;");
cSw.WriteLine("\t\t}");
cSw.WriteLine("\t\treturn null;");
cSw.WriteLine("\t}");//区分
}
else if (keyNum == 2)
{
cSw.WriteLine("\tpublic override void Init()");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tforeach (var info in DataList)");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\t_dataList.Add(info." + dicClientMembers[0] + ", info);");
cSw.WriteLine("\t\t}");
cSw.WriteLine("\t}");

cSw.WriteLine("\tpublic Dictionary<" + dicClientTypes[index[0]] + ", " + csUpName + "Excel> GetInfo()");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\treturn _dataList;");
cSw.WriteLine("\t}");

cSw.WriteLine("\tpublic " + csUpName + "Excel GetInfoById(" + dicClientTypes[index[0]] + " _id)");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tvar info = _dataList[_id];");
cSw.WriteLine("\t\tif (info != null)");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\treturn info;");
cSw.WriteLine("\t\t}");
cSw.WriteLine("\t\treturn null;");
cSw.WriteLine("\t}");
}
else if (keyNum == 3)
{

}

cSw.WriteLine("\tpublic List<" + csUpName + "Excel> GetInfoByNameAndValue(string name,int value)");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tList<"+csUpName+"Excel> tempList = new List<"+csUpName+"Excel>();");
for (int i = 0; i < index.Count; ++i)
{
if (dicClientTypes[index[i]] == "int")
{
cSw.WriteLine("\t\tif (name.Equals(\"" + dicClientMembers[index[i]] + "\"))");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\tforeach (var item in DataList)");
cSw.WriteLine("\t\t\t{");
cSw.WriteLine("\t\t\t\tif (item."+ dicClientMembers[index[i]]+"== value)");
cSw.WriteLine("\t\t\t\t\ttempList.Add(item);");
cSw.WriteLine("\t\t\t}");
cSw.WriteLine("\t\t}");
}
}
cSw.WriteLine("\t\treturn tempList;");
cSw.WriteLine("\t}");

cSw.WriteLine("\tpublic List<" + csUpName + "Excel> GetInfoByNameAndValue(string name,string value)");
cSw.WriteLine("\t{");
cSw.WriteLine("\t\tList<" + csUpName + "Excel> tempList = new List<" + csUpName + "Excel>();");
for (int i = 0; i < index.Count; ++i)
{
if (dicClientTypes[index[i]] == "string")
{
cSw.WriteLine("\t\tif (name.Equals(\"" + dicClientMembers[index[i]] + "\"))");
cSw.WriteLine("\t\t{");
cSw.WriteLine("\t\t\tforeach (var item in DataList)");
cSw.WriteLine("\t\t\t{");
cSw.WriteLine("\t\t\t\tif (item." + dicClientMembers[index[i]] + ".Equals(value))");
cSw.WriteLine("\t\t\t\t\ttempList.Add(item);");
cSw.WriteLine("\t\t\t}");
cSw.WriteLine("\t\t}");
}
}
cSw.WriteLine("\t\treturn tempList;");
cSw.WriteLine("\t}");
cSw.WriteLine("}");

cSw.Flush();
cSw.Close();
cSw.Dispose();

Debug.Log(curFileName + "  scriptableObject  file  export complete !");
}

导出玩scriptableObject类之后,就是利用反射,创建出.asset资源文件。

[code]            if (exportType == EXPORT_TYPE_ASSET)
{
string className = string.Format("DataTable{0}", csUpName);
Type type = Type.GetType(className);
string eleName = string.Format("{0}Excel", csUpName);
Type eleType = Type.GetType(eleName);

var asset = ScriptableObject.CreateInstance(type);

MethodInfo addMethod = type.GetMethod("AddInfo");

foreach (var pair in dicData)
{
var item = Activator.CreateInstance(eleType);
FieldInfo[] fields = eleType.GetFields();

for (int i = 0; i < index.Count; i++)//循环所有的列数
{
FieldInfo singleField = fields[i];
if (string.IsNullOrEmpty(pair.Value[index[i]]))//某一行的某一列
{
if (dicClientTypes[index[i]] == "string")
{
singleField.SetValue(item, Convert.ChangeType("", typeof(string)));
}
else if (dicClientTypes[index[i]] == "int")
{
singleField.SetValue(item, Convert.ChangeType(0, typeof(int)));
}
else if (dicClientTypes[index[i]] == "array")
{
singleField.SetValue(item, Convert.ChangeType(0, typeof(int[])));
}
}
else
{
if (dicClientTypes[index[i]] == "string")
{
singleField.SetValue(item, Convert.ChangeType(pair.Value[index[i]], typeof(string)));
}
else if (dicClientTypes[index[i]] == "array")
{
int[] test = GetStringToInt(pair.Value[index[i]]);
singleField.SetValue(item, test);
}
else if (dicClientTypes[index[i]] == "int" || dicClientTypes[index[i]] == "uint" || dicClientTypes[index[i]] == "float")
{
singleField.SetValue(item, Convert.ChangeType(pair.Value[index[i]], typeof(int)));
}
else
throw new Exception("配置了客户端不支持的类型");
}
}
addMethod.Invoke(asset, new object[] { item });
}

string assetPath = "Assets" + _clientPath + "DataTable" + csUpName + ".asset";

AssetDatabase.CreateAsset(asset, assetPath);

AssetDatabase.Refresh();

Debug.Log(curFileName + "  assest  file  export complete !");
}

以上就已经讲解完此导表工具的大致思路跟关键代码了。

以下为导出后的scriptableObject脚本:

以下为.asset资源文件:

简单的说,思路都是一样的,之后无论是想要导出lua、java、二进制等等,只要在导出的时候,编写不同的导出模式,以及跟自己项目中的数据管理模块相接就可以了。

目前,我的小项目中数据管理模块,使用数据的方式,我个人感觉不是很好,在做更好的优化处理,所以看了博客的朋友们,再次提醒,文章志在提供思路。大神们有更好的方式,可以给我留个言,我会努力深入探讨研究的。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: