欢迎关注个人公众号:游戏码小喵
在游戏开发过程中,读取配置文件是必不可少的,读取配置文件的方式有多种多样。转Unity差不多1年了,有很多知识学了忘,忘了学,现在希望通过写文章的方式记录一些东西,以防再忘记,也希望我的文章能帮助那些像我一样刚入门的程序员。
废话不多少,开始正题。下面说说这系列的文章都要写些什么。昨天看到知乎上一个名为毛豆爹的文章回复中这样写到 “对于不同的数据采用不同的配置方法,不要什么数据都用excel,对于有可视化需求的配置,比如ui或者角色身上需要装配一些武器的,提供可视化的工具。对于需要描述父子关系的例如技能树解锁之类的用json或者xml来描述,对于纯数字逻辑的就用csv就好了。” 所以这一些列文章就打算写写配置文件的加载方式。
计划分为四篇文章,分别为:
从Excel文件中读取,这种方式我已经实现过了,但是后面三种本人还未动手实现。这也让我有动力学习一下后三种方式,在未来的几周我会逐一学习,然后把自己的所得分享出来。让大家见笑了,也希望得到大家的意见和建议。
现在大多数公司,大多数项目都会通过Excel配置游戏中用到的数据,今天就说说我从Excel中读取配置的方式。
我的方式是这样的:从Excel文件中读文件保存到ScriptableObject数据格式中,保存在项目中,然后运行游戏的时候从 ScriptableObject文件中读取需要的数据。
这种方式中需要做的几个步骤:
下面分别对这3个步骤进行分析:(在项目中需要导入Excel.dll和System.Data.dll两个库,https://pan.baidu.com/s/1mimIkGg, 提取码 4mhm)
解释一下:
第1行:注释,策划能够清楚配置的列是什么意思(在生成的类中也用于注释);
第2行:属性,(在生成类中用于属性名,例如:Id这个属性,会在类中生成一个id变量和其对应的Id的get,set方法)
第3行:属性的类型,(在生成类中用于属性的类型,Int32对应int,String对应string,Single 对应float,为什么这样配置?
是因为在System命令空间中只能找到Int32,String,Single等属性)
第4行之后:为游戏中需要用到的数据
string[] excelFiles = Directory.GetFiles(EditorStaticValue.DataFolderPath);
foreach (string fileName in excelFiles)
{
if (fileName.EndsWith("xlsx"))
{
string[] pathFiled = fileName.Split('/');
if (pathFiled.Length > 0)
{
string xlsfileName = pathFiled[pathFiled.Length - 1];
DataSet dataSet = ReadExcel(xlsfileName);
DataTableCollection tables = dataSet.Tables;
// CreateExcelClass(tables[0].TableName, tables[0].Rows);
foreach(DataTable table in tables)
{
CreateExcelClass(table.TableName, table.Rows);
}
}
}
}
private static void CreateExcelClass(string tableName, DataRowCollection collection)
{
object[] propertyRow = collection[0].ItemArray;
List allColumnStrList = new List();
allColumnStrList.Add(GetColumnString(propertyRow));
for (int row = 1; row < collection.Count; row++)
{
allColumnStrList.Add(GetColumnString(collection[row].ItemArray));
}
string[] fileLineContent = allColumnStrList.ToArray();
if (fileLineContent.Length > 0)
{
//注释的名字
string[] noteContents = fileLineContent[0].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的名字
string[] VariableNameContents = fileLineContent[1].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的类型
string[] TypeNameContents = fileLineContent[2].Split(new string[] {"$"}, System.StringSplitOptions.None);
AutoCreateClass(tableName, TypeNameContents, VariableNameContents, noteContents,
EditorStaticValue.OutClassNameSpace);
}
}
private static string GetColumnString(object[] rowData)
{
List ss = new List();
for (int i = 0; i < rowData.Length; i++)
{
ss.Add(rowData[i].ToString());
}
return string.Join("$", ss.ToArray());
}
allColumnStrList = new List();
allColumnStrList.Add(GetColumnString(propertyRow));
for (int row = 1; row < collection.Count; row++)
{
allColumnStrList.Add(GetColumnString(collection[row].ItemArray));
}
string[] fileLineContent = allColumnStrList.ToArray();
if (fileLineContent.Length > 0)
{
//注释的名字
string[] noteContents = fileLineContent[0].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的名字
string[] VariableNameContents = fileLineContent[1].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的类型
string[] TypeNameContents = fileLineContent[2].Split(new string[] {"$"}, System.StringSplitOptions.None);
AutoCreateClass(tableName, TypeNameContents, VariableNameContents, noteContents,
EditorStaticValue.OutClassNameSpace);
}
}
private static string GetColumnString(object[] rowData)
{
List ss = new List();
for (int i = 0; i < rowData.Length; i++)
{
ss.Add(rowData[i].ToString());
}
return string.Join("$", ss.ToArray());
}
private static void AutoCreateClass(string className, string[] typeNames, string[] propertyNames, string[] noteNames, string nameSpace)
{
//声明自定义类
CodeTypeDeclaration customerClass = new CodeTypeDeclaration(className);
customerClass.IsClass = true;
customerClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
customerClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
CodeCompileUnit customerUnit = new CodeCompileUnit();//创建代码单元
string ExtensionsClassName = string.Format("{0}{1}", className, "Extend");
CodeTypeDeclaration customerExtensionsClass = new CodeTypeDeclaration(ExtensionsClassName);
customerExtensionsClass.IsClass = true;
customerExtensionsClass.TypeAttributes = TypeAttributes.Public;
CodeCompileUnit customerExtensionsUnit = new CodeCompileUnit();//创建代码单元
//创建命名空间
if (!string.IsNullOrEmpty(nameSpace))
{
CodeNamespace customerNameSpace = new CodeNamespace(nameSpace);
customerNameSpace.Imports.AddRange(new CodeNamespaceImport[] { new CodeNamespaceImport("System") });
customerNameSpace.Types.Add(customerClass);
customerUnit.Namespaces.Add(customerNameSpace);
CodeNamespace customerExtensionsNameSpace = new CodeNamespace(nameSpace);
customerExtensionsNameSpace.Types.Add(customerExtensionsClass);
customerExtensionsUnit.Namespaces.Add(customerExtensionsNameSpace);
}
for (var i = 0; i < propertyNames.Length; i++)
{
string propertyName = propertyNames[i];
//创建类中的变量
// Type.GetType(string.Format("System.{0}", typeNames[i]));
string fieldName = propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
CodeMemberField field = new CodeMemberField(Type.GetType(string.Format("System.{0}", typeNames[i])), fieldName);
field.Attributes = MemberAttributes.Public;
customerClass.Members.Add(field);
//创建类中的属性
CodeMemberProperty property = new CodeMemberProperty();
property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
property.Name = propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1);
property.HasGet = true;
property.HasSet = true;
property.Type = new CodeTypeReference(Type.GetType(string.Format("System.{0}", typeNames[i])));
property.Comments.Add(new CodeCommentStatement(noteNames[i]));
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()));
customerClass.Members.Add(property);
}
//创建代码生成类-C#
CodeDomProvider providerCS = CodeDomProvider.CreateProvider("C#");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
options.BlankLinesBetweenMembers = true;
//生成代码
string outputFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigClassPath, className);
using (StreamWriter sw = new StreamWriter(outputFile))
{
providerCS.GenerateCodeFromCompileUnit(customerUnit, sw, options);
}
string outputExtensionsFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigExtendClassPath, ExtensionsClassName);
if (!File.Exists(outputExtensionsFile))
{
using (StreamWriter sw = new StreamWriter(outputExtensionsFile))
{
providerCS.GenerateCodeFromCompileUnit(customerExtensionsUnit, sw, options);
}
}
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("输出类文件", "成功输出所有类文件!!", "确定");
}
using System.Collections.Generic;
using ConfigClassExport;
using UnityEngine;
namespace Assets.Scripts.Config.DataBase
{
public class ConfigData : ScriptableObject
{
public DataScene[] DataSceneList;
public DataPlayer[] DataPlayerList;
}
}
private static void AddDataToHolder(string className, DataRowCollection collection)
{
int index = 0;
object[] propertyRow = collection[EditorStaticValue.ExcelPropertyLine].ItemArray;
var str = string.Format("{0}.{1}", EditorStaticValue.OutClassNameSpace, className);
var elementNum = collection.Count - EditorStaticValue.ExcelValueLineStart;
var arr = Array.CreateInstance(CureentAssembly.GetType(str), elementNum);
for (int row = EditorStaticValue.ExcelValueLineStart; row < collection.Count; row++)
{
// object obj = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(str, false);
object obj = CureentAssembly.CreateInstance(str, false);
if (obj == null)
return;
if (collection[row].IsNull(0))
{
continue;
}
for (int i = 0; i < propertyRow.Length; i++)
{
string propertyName = propertyRow[i].ToString();
if (string.IsNullOrEmpty(propertyName))
{
continue;
}
PropertyInfo info = obj.GetType().GetProperty(propertyName);
if (info == null)
{
throw new Exception(string.Format("{0}.cs中{1}属性无法获取,检查是否少写了{1}属性!!!", className, propertyName));
}
if (info.PropertyType.IsArray)
{
string s = collection[row][i].ToString();
var strArr = s.Split(',');
var n = strArr.Length;
Type elementType = info.PropertyType.GetElementType();
var arr11 = Array.CreateInstance(elementType, n);
for(int j=0;j
然后在运行游戏的时候读取这个scriptableObject,加载数据存在字典中就行了
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using Assets.Scripts.Comman;
using Assets.Scripts.Config.DataBase;
using Excel;
using UnityEditor;
using UnityEngine;
namespace Assets.Editor
{
public class ConfigEditor {
[MenuItem("游戏配置/1 -> 生成Excel对应的Class", false, 1001)]
private static void Excel2Class()
{
if (CreateAllFolder())
{
string[] excelFiles = Directory.GetFiles(EditorStaticValue.DataFolderPath);
foreach (string fileName in excelFiles)
{
if (fileName.EndsWith("xlsx"))
{
string[] pathFiled = fileName.Split('/');
if (pathFiled.Length > 0)
{
string xlsfileName = pathFiled[pathFiled.Length - 1];
DataSet dataSet = ReadExcel(xlsfileName);
DataTableCollection tables = dataSet.Tables;
// CreateExcelClass(tables[0].TableName, tables[0].Rows);
foreach(DataTable table in tables)
{
CreateExcelClass(table.TableName, table.Rows);
}
}
}
}
}
AssetDatabase.Refresh();
}
private static string currentExcelName = "";
[MenuItem("游戏配置/2 -> 生成游戏中使用的配置文件", false, 1001)]
private static void CreateScriptObject()
{
ConfigData data = ScriptableObject.CreateInstance();
ExcelAccess.SelectConfigExcel(ref data);
if (!Directory.Exists(EditorStaticValue.ConfigScriptObjectPath))
{
Directory.CreateDirectory(EditorStaticValue.ConfigScriptObjectPath);
}
AssetDatabase.CreateAsset(data, EditorStaticValue.ConfigScriptObjectPath + "Config.asset");
AssetDatabase.Refresh();
}
private static DataSet ReadExcel(string excelName)
{
string path = FilePath(excelName);
try
{
FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
return result;
}
catch (Exception ex)
{
string[] strArr = ex.Message.Split('\\');
throw new Exception(string.Format("先关闭{0}", strArr[strArr.Length - 1]));
}
}
private static string FilePath(string path)
{
return EditorStaticValue.DataFolderPath + "/" + path;
}
private static void CreateExcelClass(string tableName, DataRowCollection collection)
{
object[] propertyRow = collection[0].ItemArray;
List allColumnStrList = new List();
allColumnStrList.Add(GetColumnString(propertyRow));
for (int row = 1; row < collection.Count; row++)
{
allColumnStrList.Add(GetColumnString(collection[row].ItemArray));
}
string[] fileLineContent = allColumnStrList.ToArray();
if (fileLineContent.Length > 0)
{
//注释的名字
string[] noteContents = fileLineContent[0].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的名字
string[] VariableNameContents = fileLineContent[1].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的类型
string[] TypeNameContents = fileLineContent[2].Split(new string[] {"$"}, System.StringSplitOptions.None);
AutoCreateClass(tableName, TypeNameContents, VariableNameContents, noteContents,
EditorStaticValue.OutClassNameSpace);
}
}
private static bool CreateAllFolder()
{
if (!Directory.Exists(EditorStaticValue.DataFolderPath))
{
Directory.CreateDirectory(EditorStaticValue.DataFolderPath);
Debug.LogError(string.Format("把xlsx配置文件放入{0}文件夹内", EditorStaticValue.DataFolderPath));
return false;
}
if (!Directory.Exists(EditorStaticValue.OutConfigClassPath))
{
Directory.CreateDirectory(EditorStaticValue.OutConfigClassPath);
}
else
{
DeleteAllFileInFolder(EditorStaticValue.OutConfigClassPath, "OutConfigClassPath Class");
}
if (!Directory.Exists(EditorStaticValue.OutConfigExtendClassPath))
{
Directory.CreateDirectory(EditorStaticValue.OutConfigExtendClassPath);
}
return true;
}
private static string GetColumnString(object[] rowData)
{
List ss = new List();
for (int i = 0; i < rowData.Length; i++)
{
ss.Add(rowData[i].ToString());
}
return string.Join("$", ss.ToArray());
}
private static void DeleteAllFileInFolder(string path, string note)
{
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files = dir.GetFiles();
foreach (var item in files)
{
File.Delete(item.FullName);
}
// Debug.Log(string.Format("成功删除所有{0}文件!!", note));
}
///
/// 自动生成类
///
///类名.
///属性名称数组.
///注释数组.
///命名空间.
private static void AutoCreateClass(string className, string[] typeNames, string[] propertyNames, string[] noteNames, string nameSpace)
{
//声明自定义类
CodeTypeDeclaration customerClass = new CodeTypeDeclaration(className);
customerClass.IsClass = true;
customerClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
customerClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
CodeCompileUnit customerUnit = new CodeCompileUnit();//创建代码单元
string ExtensionsClassName = string.Format("{0}{1}", className, "Extend");
CodeTypeDeclaration customerExtensionsClass = new CodeTypeDeclaration(ExtensionsClassName);
customerExtensionsClass.IsClass = true;
customerExtensionsClass.TypeAttributes = TypeAttributes.Public;
CodeCompileUnit customerExtensionsUnit = new CodeCompileUnit();//创建代码单元
//创建命名空间
if (!string.IsNullOrEmpty(nameSpace))
{
CodeNamespace customerNameSpace = new CodeNamespace(nameSpace);
customerNameSpace.Imports.AddRange(new CodeNamespaceImport[] { new CodeNamespaceImport("System") });
customerNameSpace.Types.Add(customerClass);
customerUnit.Namespaces.Add(customerNameSpace);
CodeNamespace customerExtensionsNameSpace = new CodeNamespace(nameSpace);
customerExtensionsNameSpace.Types.Add(customerExtensionsClass);
customerExtensionsUnit.Namespaces.Add(customerExtensionsNameSpace);
}
for (var i = 0; i < propertyNames.Length; i++)
{
string propertyName = propertyNames[i];
//创建类中的变量
// Type.GetType(string.Format("System.{0}", typeNames[i]));
string fieldName = propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
CodeMemberField field = new CodeMemberField(Type.GetType(string.Format("System.{0}", typeNames[i])), fieldName);
field.Attributes = MemberAttributes.Public;
customerClass.Members.Add(field);
//创建类中的属性
CodeMemberProperty property = new CodeMemberProperty();
property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
property.Name = propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1);
property.HasGet = true;
property.HasSet = true;
property.Type = new CodeTypeReference(Type.GetType(string.Format("System.{0}", typeNames[i])));
property.Comments.Add(new CodeCommentStatement(noteNames[i]));
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()));
customerClass.Members.Add(property);
}
//创建代码生成类-C#
CodeDomProvider providerCS = CodeDomProvider.CreateProvider("C#");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
options.BlankLinesBetweenMembers = true;
//生成代码
string outputFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigClassPath, className);
using (StreamWriter sw = new StreamWriter(outputFile))
{
providerCS.GenerateCodeFromCompileUnit(customerUnit, sw, options);
}
string outputExtensionsFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigExtendClassPath, ExtensionsClassName);
if (!File.Exists(outputExtensionsFile))
{
using (StreamWriter sw = new StreamWriter(outputExtensionsFile))
{
providerCS.GenerateCodeFromCompileUnit(customerExtensionsUnit, sw, options);
}
}
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("输出类文件", "成功输出所有类文件!!", "确定");
}
}
}
();
ExcelAccess.SelectConfigExcel(ref data);
if (!Directory.Exists(EditorStaticValue.ConfigScriptObjectPath))
{
Directory.CreateDirectory(EditorStaticValue.ConfigScriptObjectPath);
}
AssetDatabase.CreateAsset(data, EditorStaticValue.ConfigScriptObjectPath + "Config.asset");
AssetDatabase.Refresh();
}
private static DataSet ReadExcel(string excelName)
{
string path = FilePath(excelName);
try
{
FileStream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
DataSet result = excelReader.AsDataSet();
return result;
}
catch (Exception ex)
{
string[] strArr = ex.Message.Split('\\');
throw new Exception(string.Format("先关闭{0}", strArr[strArr.Length - 1]));
}
}
private static string FilePath(string path)
{
return EditorStaticValue.DataFolderPath + "/" + path;
}
private static void CreateExcelClass(string tableName, DataRowCollection collection)
{
object[] propertyRow = collection[0].ItemArray;
List allColumnStrList = new List();
allColumnStrList.Add(GetColumnString(propertyRow));
for (int row = 1; row < collection.Count; row++)
{
allColumnStrList.Add(GetColumnString(collection[row].ItemArray));
}
string[] fileLineContent = allColumnStrList.ToArray();
if (fileLineContent.Length > 0)
{
//注释的名字
string[] noteContents = fileLineContent[0].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的名字
string[] VariableNameContents = fileLineContent[1].Split(new string[] {"$"}, System.StringSplitOptions.None);
//变量的类型
string[] TypeNameContents = fileLineContent[2].Split(new string[] {"$"}, System.StringSplitOptions.None);
AutoCreateClass(tableName, TypeNameContents, VariableNameContents, noteContents,
EditorStaticValue.OutClassNameSpace);
}
}
private static bool CreateAllFolder()
{
if (!Directory.Exists(EditorStaticValue.DataFolderPath))
{
Directory.CreateDirectory(EditorStaticValue.DataFolderPath);
Debug.LogError(string.Format("把xlsx配置文件放入{0}文件夹内", EditorStaticValue.DataFolderPath));
return false;
}
if (!Directory.Exists(EditorStaticValue.OutConfigClassPath))
{
Directory.CreateDirectory(EditorStaticValue.OutConfigClassPath);
}
else
{
DeleteAllFileInFolder(EditorStaticValue.OutConfigClassPath, "OutConfigClassPath Class");
}
if (!Directory.Exists(EditorStaticValue.OutConfigExtendClassPath))
{
Directory.CreateDirectory(EditorStaticValue.OutConfigExtendClassPath);
}
return true;
}
private static string GetColumnString(object[] rowData)
{
List ss = new List();
for (int i = 0; i < rowData.Length; i++)
{
ss.Add(rowData[i].ToString());
}
return string.Join("$", ss.ToArray());
}
private static void DeleteAllFileInFolder(string path, string note)
{
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files = dir.GetFiles();
foreach (var item in files)
{
File.Delete(item.FullName);欢迎关注个人公众号:游戏码小喵欢迎关注个人公众号:游戏码小喵
}
// Debug.Log(string.Format("成功删除所有{0}文件!!", note));
}
///
/// 自动生成类
///
///类名.
///属性名称数组.
///注释数组.
///命名空间.
private static void AutoCreateClass(string className, string[] typeNames, string[] propertyNames, string[] noteNames, string nameSpace)
{
//声明自定义类
CodeTypeDeclaration customerClass = new CodeTypeDeclaration(className);
customerClass.IsClass = true;
customerClass.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
customerClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute))));
CodeCompileUnit customerUnit = new CodeCompileUnit();//创建代码单元
string ExtensionsClassName = string.Format("{0}{1}", className, "Extend");
CodeTypeDeclaration customerExtensionsClass = new CodeTypeDeclaration(ExtensionsClassName);
customerExtensionsClass.IsClass = true;
customerExtensionsClass.TypeAttributes = TypeAttributes.Public;
CodeCompileUnit customerExtensionsUnit = new CodeCompileUnit();//创建代码单元
//创建命名空间
if (!string.IsNullOrEmpty(nameSpace))
{
CodeNamespace customerNameSpace = new CodeNamespace(nameSpace);
customerNameSpace.Imports.AddRange(new CodeNamespaceImport[] { new CodeNamespaceImport("System") });
customerNameSpace.Types.Add(customerClass);
customerUnit.Namespaces.Add(customerNameSpace);
CodeNamespace customerExtensionsNameSpace = new CodeNamespace(nameSpace);
customerExtensionsNameSpace.Types.Add(customerExtensionsClass);
customerExtensionsUnit.Namespaces.Add(customerExtensionsNameSpace);
}
for (var i = 0; i < propertyNames.Length; i++)
{
string propertyName = propertyNames[i];
//创建类中的变量
// Type.GetType(string.Format("System.{0}", typeNames[i]));
string fieldName = propertyName.Substring(0, 1).ToLower() + propertyName.Substring(1);
CodeMemberField field = new CodeMemberField(Type.GetType(string.Format("System.{0}", typeNames[i])), fieldName);
field.Attributes = MemberAttributes.Public;
customerClass.Members.Add(field);
//创建类中的属性
CodeMemberProperty property = new CodeMemberProperty();
property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
property.Name = propertyName.Substring(0, 1).ToUpper() + propertyName.Substring(1);
property.HasGet = true;
property.HasSet = true;
property.Type = new CodeTypeReference(Type.GetType(string.Format("System.{0}", typeNames[i])));
property.Comments.Add(new CodeCommentStatement(noteNames[i]));
property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()));
customerClass.Members.Add(property);
}
//创建代码生成类-C#
CodeDomProvider providerCS = CodeDomProvider.CreateProvider("C#");
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BracingStyle = "C";
options.BlankLinesBetweenMembers = true;
//生成代码
string outputFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigClassPath, className);
using (StreamWriter sw = new StreamWriter(outputFile))
{
providerCS.GenerateCodeFromCompileUnit(customerUnit, sw, options);
}
string outputExtensionsFile = string.Format("{0}{1}.cs", EditorStaticValue.OutConfigExtendClassPath, ExtensionsClassName);
if (!File.Exists(outputExtensionsFile))
{
using (StreamWriter sw = new StreamWriter(outputExtensionsFile))
{
providerCS.GenerateCodeFromCompileUnit(customerExtensionsUnit, sw, options);
}
}
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("输出类文件", "成功输出所有类文件!!", "确定");
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using Assets.Scripts.Comman;
using Excel;
using UnityEngine;
using System.Reflection;
using Assets.Scripts.Config.DataBase;
namespace Assets.Editor
{
public class ExcelAccess {
public static Assembly CureentAssembly = Assembly.Load("Assembly-CSharp");
public static Assembly EdiotrAssembly = Assembly.Load("Assembly-CSharp-Editor");
private static ConfigData _holder;
// private static string currentExcelName = "";
public static void SelectConfigExcel(ref ConfigData holder)
{
_holder = holder;
string path = Application.dataPath + "/Config/";
string[] excelFiles = Directory.GetFiles(path);
foreach (string fileName in excelFiles)
{
if (fileName.EndsWith("xlsx"))
{
string[] pathFiled = fileName.Split('/');
if (pathFiled.Length > 0)
{
string xlsfileName = pathFiled[pathFiled.Length - 1];
// currentExcelName = xlsfileName;
DataSet dataSet = ReadExcel(xlsfileName);
DataTableCollection tables = dataSet.Tables;
for (int j = 0; j < tables.Count; j++)
{
AddDataToHolder(tables[j].TableName, tables[j].Rows);
}
}
}
}
}
private static void AddDataToHolder(string className, DataRowCollection collection)
{
int index = 0;
object[] propertyRow = collection[EditorStaticValue.ExcelPropertyLine].ItemArray;
var str = string.Format("{0}.{1}", EditorStaticValue.OutClassNameSpace, className);
var elementNum = collection.Count - EditorStaticValue.ExcelValueLineStart;
var arr = Array.CreateInstance(CureentAssembly.GetType(str), elementNum);
for (int row = EditorStaticValue.ExcelValueLineStart; row < collection.Count; row++)
{
// object obj = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(str, false);
object obj = CureentAssembly.CreateInstance(str, false);
if (obj == null)
return;
if (collection[row].IsNull(0))
{
continue;
}
for (int i = 0; i < propertyRow.Length; i++)
{
string propertyName = propertyRow[i].ToString();
if (string.IsNullOrEmpty(propertyName))
{
continue;
}
PropertyInfo info = obj.GetType().GetProperty(propertyName);
if (info == null)
{
throw new Exception(string.Format("{0}.cs中{1}属性无法获取,检查是否少写了{1}属性!!!", className, propertyName));
}
if (info.PropertyType.IsArray)
{
string s = collection[row][i].ToString();
var strArr = s.Split(',');
var n = strArr.Length;
Type elementType = info.PropertyType.GetElementType();
var arr11 = Array.CreateInstance(elementType, n);
for(int j=0;j
using UnityEngine;
namespace Assets.Scripts.Comman
{
public class EditorStaticValue
{
public static readonly string DataFolderPath = Application.dataPath + "/Config/";
public static readonly string OutConfigClassPath = Application.dataPath + "/Scripts/Config/ConfigDataBase/";
public static readonly string OutConfigExtendClassPath = Application.dataPath + "/Scripts/Config/ConfigExtend/";
public static readonly string OutClassNameSpace = "ConfigClassExport";
public static readonly string ConfigScriptObjectPath = "Assets/Resources/ConfigAsset/";
public static readonly int ExcelPropertyLine = 1;
public static readonly int ExcelValueLineStart = 3;
public static readonly string LocalConfigAssetNames = "ConfigAsset/Config";
}
}
欢迎关注个人公众号:游戏码小喵