Unity编辑器扩展:导表工具(1)(通用版)
以下均为我个人总结的方案,如果有所不足的地方,请多多包涵
有更好的方案或者有错误之处,敬请留言,谢谢您看了我的博客
最近开始捣弄自己的小项目,想了想怎么开始,我个人的想法也就是从导表工具开始入手。
此文章志在提供思路,以及部分代码,涉及的关键性问题会详细阐述。
目前此工具我已经开发了部分功能,支持Json,ScriptableObject,asset文件,至于java,lua等其他语言,只要理解了思路,都是同样的道理。
因为我的小项目是单机的,所以按照我的思路,一开始原本用json,后面改用scripttableObject以及asset文件。
简单说明下思路:分三个步骤
1.编辑器扩展,编写界面。
2.如何读取excel表中数据。
3.将数据转换成自己想要的格式。
简单来说,就是自己的项目定义好excel表内数据格式,然后读取之后,讲数据转化成自己想要的格式就好了。
我的工具最终效果如图:
一:编辑器扩展界面编写
将工具放入菜单栏中,如图所示
至于编辑器扩展相关知识,我也不是编写过很多,相关知识点等以后我学习更深,总结后再发布到《学习》类别里。
至于编辑器界面编写,有很多种GUI系统,基于我自己项目对于界面自定义需求不高,我使用带自动布局的EditorGUI系统。
[code] EditorGUILayout.BeginHorizontal(); _threePackName = EditorGUILayout.TextField("数据类型:", _threePackName); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); _excelPath = EditorGUILayout.TextField("excel目录:", _excelPath); if (GUILayout.Button( "Browse",GUILayout.ExpandWidth(false))) { string path = EditorUtility.OpenFolderPanel("", "", ""); if (path != null) { _excelPath = path; Debug.LogWarning("Select _excelPath folder = "+_excelPath); EditorPrefs.SetString(SAVE_CLIENT_EXCLE_PATH, _excelPath); GetExcelFileInfos();//这里是在选择了excel目录后再读取目录中所有excel文件的操 //作。在后面会做详细阐述 } } EditorGUILayout.EndHorizontal();
简单说明下:
第一个数据类型,是为了以后方便区分不同语言版本。
第二个excel目录,是excel目录文件的路径,这里使用了EditorPrefs来做存储,为了是方便再次打工工具时候使用。
以此类推,编辑器界面除了excel文件展示部分,其余部分都很简单。
接下来是excel文件部分:
首先,需要个excel数据类、MD5数据类
[code] /// <summary> /// excel数据类 /// </summary> public class FileInfoData { /// <summary> /// Excel表的路径 /// </summary> public string filePath; public string fileNameWithPostfix; /// <summary> /// Excel表的名字 /// </summary> public string fileName; public string fileNewName; /// <summary> /// Excel表的MD5存储 /// </summary> public string excelMD5Save; /// <summary> /// Excel表的新MD5 /// </summary> public string excelMD5New; public bool toLua; public bool toJson; public bool toScript; public bool toAsset; public bool toJava; } public class MD5Item { public MD5Item(string md5, bool tolua, bool tojson, bool toscript, bool toasset, bool tojava) { MD5 = md5; toLua = tolua; toJson = tojson; toScript = toscript; toAsset = toasset; toJava = tojava; } public string MD5; public bool toLua; public bool toJson; public bool toScript; public bool toAsset; public bool toJava; }
有了以上两个数据类,就可以实现GetExcelFileInfos函数,就是在第一个代码块内的函数。
说明下GetExcelFileInfos函数,里面将第一个代码块中,excel目录路径,以及语言拼接,再获取路径里面的所有excel文件,再讲各个文件的MD5进行比较判断,判断出文件是否已经导出过,而后在界面展示中,展示出不同的颜色,以区分已经导出过的文件。
[code] private Dictionary<string, MD5Item> MD5List = new Dictionary<string, MD5Item>(); private List<FileInfoData> fileInfos = new List<FileInfoData>(); /// <summary> /// 获取所有的Excel文件 /// </summary> private void GetExcelFileInfos() { string curExcelFolderLocation = _excelPath + "/" + _threePackName + "/"; fileInfos.Clear(); List<string> fileList = new List<string>(); fileList.AddRange(Directory.GetFiles(curExcelFolderLocation, "*", SearchOption.AllDirectories)); fileList.Sort(); for (int i = 0; i < fileList.Count; i++) { string filePath = fileList[i].Replace("\\", "/"); string fileName = filePath.Substring(filePath.LastIndexOf("/") + 1); if (!(fileName.EndsWith(".xlsx") || fileName.EndsWith(".xlsm") || fileName.EndsWith(".xls")) || fileName.StartsWith("~$") || fileName.IndexOf("name_filter") >= 0 || fileName.IndexOf("chat_filter") >= 0 ) { continue; } string fileNameWithPostfix = fileName; fileName = fileName.Substring(0, fileName.IndexOf(".")); FileInfoData curFileInfo = new FileInfoData(); curFileInfo.filePath = filePath; curFileInfo.fileNameWithPostfix = fileNameWithPostfix; curFileInfo.fileName = fileName; curFileInfo.fileNewName = fileName.ToUpper().Substring(0, 1) + fileName.Substring(1); MD5Item item = null; if (MD5List.TryGetValue(fileName, out item)) { curFileInfo.excelMD5Save = item.MD5; curFileInfo.toLua = item.toLua; curFileInfo.toJson = item.toJson; curFileInfo.toScript = item.toScript; curFileInfo.toAsset = item.toAsset; curFileInfo.toJava = item.toJava; } else { curFileInfo.excelMD5Save = ""; curFileInfo.toLua = false; curFileInfo.toJson = false; curFileInfo.toScript = false; curFileInfo.toAsset = false; curFileInfo.toJava = false; } FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); curFileInfo.excelMD5New = MD5Hash.Get(fs); if (curFileInfo.excelMD5New != curFileInfo.excelMD5Save) { curFileInfo.toLua = false; curFileInfo.toJson = false; curFileInfo.toScript = false; curFileInfo.toAsset = false; curFileInfo.toJava = false; } fs.Close(); fileInfos.Add(curFileInfo); } fileInfos.Sort(compareFileInfos); } static int compareFileInfos(FileInfoData a,FileInfoData b) { return string.Compare(a.fileName, b.fileName); }
在获取了所有文件信息,存储在fileInfos里面后,就可以在编辑器最底部做展示,然后根据相应文件的点击,导出所想要的格式。
[code] void SearchGUI() { GUI.color = Color.white; GUILayout.Label( "提示-------------------------------------------------------------------------:"); _search = EditorGUILayout.TextField("搜索关键词:", _search); } private Vector2 _scroll_pos; void BottomGUI() { _scroll_pos = EditorGUILayout.BeginScrollView(_scroll_pos); { foreach (FileInfoData fi in fileInfos) { if (!string.IsNullOrEmpty(_search)) { if (!fi.fileName.Contains(_search)) { continue; } } EditorGUILayout.BeginHorizontal(); if (fi.toLua) GUI.color = Color.red; else GUI.color = Color.green; if (GUILayout.Button("导出 " + fi.fileName + " 的lua文件", GUILayout.Height(40), GUILayout.Width(226))) { Debug.Log("开始导出 " + fi.filePath + " 的lua文件"); } if (fi.toJson) GUI.color = Color.red; else GUI.color = Color.green; if (GUILayout.Button("导出 " + fi.fileName + " 的json文件", GUILayout.Height(40), GUILayout.Width(226))) { Debug.Log("开始导出 " + fi.filePath + " 的json文件"); UpdateClientData(fi,EXPORT_TYPE_JSON); } if (fi.toScript) GUI.color = Color.red; else GUI.color = Color.green; if (GUILayout.Button("导出 " + fi.fileName + " 的脚本文件", GUILayout.Height(40), GUILayout.Width(226))) { Debug.Log("开始导出 " + fi.filePath + " 的脚本文件"); UpdateClientData(fi, EXPORT_TYPE_SCRIPT); } if (fi.toAsset) GUI.color = Color.red; else GUI.color = Color.green; if (GUILayout.Button("导出 " + fi.fileName + " 的Asset文件", GUILayout.Height(40), GUILayout.Width(226))) { Debug.Log("开始导出 " + fi.filePath + " 的Asset文件"); UpdateClientData(fi, EXPORT_TYPE_ASSET); } if (fi.toJava) GUI.color = Color.red; else GUI.color = Color.green; if (GUILayout.Button("导出 " + fi.fileName + " 的java文件", GUILayout.Height(40), GUILayout.Width(226))) { Debug.Log("开始导出 " + fi.filePath + " 的java文件"); } EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndScrollView(); }
以上就是编辑器界面的编写,阐述了主要的思路,以及主要的代码部分。
在上面这个代码块中,导出数据的函数为UpdateClientData,此函数将在后面篇章叙述。
至于工具中间部分,所有的一键导出,其实就是循环所有的文件,做出导出的处理。
篇章根据步骤,分为三个篇章。
- Unity编辑器扩展:导表工具(3)(通用版)
- Unity编辑器扩展:导表工具(2)(通用版)
- 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