优化版:
https://blog.csdn.net/qq_28474981/article/details/98076465
1.运行环境
1.1编辑器版本
使用Unity2017.3.1f
1.2 dll
(1)EPPlus
(2)Excel
(3)ICSharpCode.SharpZipLib
(4)System.Data(是mono文件夹底下的dll)
2.流程
1.读取目标excel文件,获取到它的前三行数据(分别为变量名,数据类型,中文名)
2.通过对前三行数据进行组合,形成可序列化的结构类以及存储多个具体数据的数据类
3.代码实现
3.1窗口
代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
public class ConfigEditorWindow: EditorWindow
{
List<FileInfo> files = new List<FileInfo>();
int lastSelectFileCount = 0;
string lastSelectAssetGUID;
[MenuItem("ResTools/Config/ConfigEditorWindow")]
static void OpenConfigEditorWindow()
{
EditorWindow.GetWindow<ConfigEditorWindow>();
}
private void OnGUI()
{
GUILayout.BeginVertical();
GUILayout.Space(10);
GUILayout.Label("需要生成代码的配置文件列表");
GUILayout.Space(15);
if (Selection.assetGUIDs.Length != lastSelectFileCount ||
(Selection.assetGUIDs.Length > 0 && lastSelectAssetGUID != Selection.assetGUIDs[Selection.assetGUIDs.Length - 1]))
{
files.Clear();
lastSelectFileCount = Selection.assetGUIDs.Length;
for (int i = 0; i < Selection.assetGUIDs.Length; i++)
{
FileInfo fileInfo =
new FileInfo(AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[i]));
if (fileInfo.Exists)
{
if (!files.Contains(fileInfo))
files.Add(fileInfo);
}
}
lastSelectAssetGUID = Selection.assetGUIDs.Last<string>();
}
for (int i = 0; i < files.Count; i++)
{
if (files[i].Exists)
{
GUILayout.BeginHorizontal();
GUILayout.Label("名称 :" + files[i].Name);
GUILayout.EndHorizontal();
}
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("生成"))
{
ConfigUtils.GenerateConfigsToCode(ConfigFileType.Excel, files,Application.dataPath+"/Scripts/Config");
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
}
实现效果:
3.2核心逻辑
代码:
using System.Text;
using ResourceSystem;
using System.Data;
using System.IO;
using UnityEngine;
using UnityEditor;
using System.Reflection;
public enum ConfigFileType
{
Excel,
}
public class ConfigUtils
{
#region 自动生成配置代码
static List<string> argsNames = new List<string>();
static List<string> argsType = new List<string>();
static List<string> argsChineseName = new List<string>();
public static void GenerateConfigsToCode(ConfigFileType fileType, List<FileInfo> fileInfos, string targetPath)
{
for(int i=0;i< fileInfos.Count;i++)
{
GenerateConfigToCode(fileType, fileInfos[i], targetPath);
}
}
public static void GenerateConfigToCode(ConfigFileType fileType,FileInfo fileInfo,string targetPath)
{
if (fileType== ConfigFileType.Excel)
{
GenerateExcelToCode(fileInfo.FullName, targetPath);
}
}
private static void GenerateExcelToCode(string path,string targetPath)
{
DataTableCollection tables = ResourceSystemFacade.Inst.ReadExcel(path);
argsNames.Clear();
argsType.Clear();
argsChineseName.Clear();
int columns = tables[0].Columns.Count;//获取列数
int rows = tables[0].Rows.Count;
for (int n = 0; n < columns; n++)
{
argsNames.Add(tables[0].Rows[0][n].ToString());
argsType.Add(tables[0].Rows[1][n].ToString());
argsChineseName.Add(tables[0].Rows[2][n].ToString());
}
string fileName = Path.GetFileNameWithoutExtension(path);
string code = GenerateCode(fileName);
if (!string.IsNullOrEmpty(code))
{
DirectoryInfo info = new DirectoryInfo(targetPath);
if (!info.Exists)
{
Directory.CreateDirectory(targetPath);
}
File.WriteAllText(targetPath +"/"+ fileName + "Info.cs", code);
}
else
{
DebugUtils.DebugError("生成代码有误");
}
}
/// <summary>
///
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private static string GenerateCode(string fileName)
{
StringBuilder code = new StringBuilder();
code.Append("using System;\nusing UnityEngine;\nusing System.Collections.Generic;\nusing ResourceSystem;\n\n");
code.Append("public class ");
code.Append(fileName);
code.Append("Info:ScriptableObject,IDataCollectionTemplete\n{");
code.Append("\n public List<");
code.Append(fileName);
code.Append("Data> Data = new List<");
code.Append(fileName);
code.Append("Data>();");
code.Append("\n /// <summary>\n ");
code.Append(" /// 获得内容Type");
code.Append("\n /// </summary>\n public Type GetContenType()\n {");
code.Append("\n return typeof(");
code.Append(fileName);
code.Append("Data);");
code.Append("\n }");
code.Append("\n /// <summary>\n ");
code.Append(" /// 转换成当前内容类型的列表");
code.Append("\n /// </summary>\n public void ConvertToContentList(List<IDataTemplete> contents)\n {");
code.Append("\n for(int i = 0; i < contents.Count; i++)\n {");
code.Append("\n Data.Add((");
code.Append(fileName);
code.Append("Data)contents[i]);");
code.Append("\n }");
code.Append("\n }");
code.Append("\n}\n\n");
code.Append("\n[Serializable]\n");
code.Append("public class ");
code.Append(fileName);
code.Append("Data:IDataTemplete\n{");
for(int i = 0; i < argsNames.Count; i++)
{
code.Append("\n /// <summary>\n ");
code.Append(" /// ");
code.Append(argsChineseName[i]);
code.Append("\n /// </summary>");
code.Append("\n public ");
code.Append(argsType[i]);
code.Append(" ");
code.Append(argsNames[i]);
code.Append("= default(");
code.Append(argsType[i]);
code.Append(");");
}
code.Append("\n /// <summary>\n ");
code.Append(" /// 反序列化");
code.Append("\n /// </summary>\n public void DeSerialize(object[] content)\n {");
for (int i = 0; i < argsNames.Count; i++)
{
code.Append("\n ");
code.Append(argsNames[i]);
if (argsType[i] == "int")
{
code.Append(" = Int32.Parse(content[");
code.Append(i);
code.Append("].ToString());");
}
else
{
code.Append(" = content[");
code.Append(i);
code.Append("].ToString();");
}
}
code.Append("\n }");
code.Append("\n}");
return code.ToString();
}
#endregion
}
实现效果:
由文件Test.xlsx
转化为数据文件
using System;
using UnityEngine;
using System.Collections.Generic;
using ResourceSystem;
public class TestInfo:ScriptableObject,IDataCollectionTemplete
{
public List<TestData> Data = new List<TestData>();
/// <summary>
/// 获得内容Type
/// </summary>
public Type GetContenType()
{
return typeof(TestData);
}
/// <summary>
/// 转换成当前内容类型的列表
/// </summary>
public void ConvertToContentList(List<IDataTemplete> contents)
{
for(int i = 0; i < contents.Count; i++)
{
Data.Add((TestData)contents[i]);
}
}
}
[Serializable]
public class TestData:IDataTemplete
{
/// <summary>
/// 索引号
/// </summary>
public int ID= default(int);
/// <summary>
/// 名称
/// </summary>
public string Name= default(string);
/// <summary>
/// 反序列化
/// </summary>
public void DeSerialize(object[] content)
{
ID = Int32.Parse(content[0].ToString());
Name = content[1].ToString();
}
}
PS:嫌Excel上两行的英文丑的话可以选择右键隐藏上面两行
可运行工程可以看:https://blog.csdn.net/qq_28474981/article/details/82749021