Unity编辑器扩展:导表工具(3)(通用版)
以下均为我个人总结的方案,如果有所不足的地方,请多多包涵
有更好的方案或者有错误之处,敬请留言,谢谢您看了我的博客
三:导出数据
此工具支持导出什么语言,区别就在这层,之前的两个步骤,与此步骤都不相关。
简单的说,需要导出的格式就在这里写,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、二进制等等,只要在导出的时候,编写不同的导出模式,以及跟自己项目中的数据管理模块相接就可以了。
目前,我的小项目中数据管理模块,使用数据的方式,我个人感觉不是很好,在做更好的优化处理,所以看了博客的朋友们,再次提醒,文章志在提供思路。大神们有更好的方式,可以给我留个言,我会努力深入探讨研究的。
- unity 编辑器工具扩展
- Unity编辑器扩展工具Shader Forge和Behavior Designer(行为树)和 Cinema Director
- unity编辑器扩展 SVN一键更新工具
- Unity编辑器之Hierarchy扩展显示隐藏节点以及图集显示
- Unity 3D - 编辑器扩展之导入文件自动设置Packing Tag
- Unity编辑器扩展记录
- Unity可扩展编辑器
- Unity编辑器扩展
- unity 编辑器扩展 扩展assert编辑器
- Unity扩展编辑器一
- 【Unity编辑器扩展简介】存储数据
- Unity 编辑器扩展教程
- Unity编辑器拓展【菜单扩展】
- Unity编辑器扩展学习笔记(一)——添加菜单选项
- [Unity]Unity3D编辑器插件扩展和组件扩展
- Unity编辑器扩展
- Unity编辑器扩展chapter1
- Unity Editor 编辑器扩展 五 EditorGUI
- unity-编辑器扩展
- Unity扩展编辑器三