使用Excel作为配置的优势
使用Excel作为配置文件有相对普通的文本文档/json等类型的配置文件有一个更好的优点,更易于编辑,更易读.譬如上面的例子,我可以制作一个人员名单,可以记录它们的姓名,年龄等信息,每一行就是一个对象,该表就是一个List.
环境准备
GitHub - ExcelDataReader/ExcelDataReader: Lightweight and fast library written in C# for reading Microsoft Excel files
选择右侧release版本中较新的版本就可以
一般下载前两个,将拓展名改为能解压的类型(7z,zip等),然后解压在lib中找到dll,一般选择.netstandard2.0/2.1.放到Unity项目的Plugins文件夹下
代码
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using ExcelDataReader;//引入命名空间
using UnityEngine;namespace Project.Utility
{public class Person{public string name;public int age;public int gender;public string hobby;}public class GetConfigUtility {/// <summary>/// 加载Excel配置,必须放在StreamingAssets/ConfigFiles下(必须放在StreamingAssets下)/// </summary>/// <param name="excelFileName">文件名(需加文件后缀)</param>/// <returns>返回一个Dictionary(表名,表)</returns>public Dictionary<string, DataTable> GetExcelConfig(string excelFileName){//拼接路径string path = Path.Combine(Application.streamingAssetsPath, "ConfigFiles", excelFileName);//获得该Excel文件的流using (var stream = File.Open(path, FileMode.Open, FileAccess.Read)){//这个流给到ExcelReaderFactory,创建一个ExcelReader对象using (var reader = ExcelReaderFactory.CreateReader(stream)){// 配置 DataSet 读取var conf = new ExcelDataSetConfiguration{ConfigureDataTable = _ => new ExcelDataTableConfiguration{UseHeaderRow = true // 使用第一行作为列标题}};//实例一个字典,键是表名(因为可以获取很多张表),值是一个表的对象Dictionary<string, DataTable> dataTableDic = new Dictionary<string, DataTable>();var dataSet = reader.AsDataSet(conf);//获取一个DataSet对象//从DataSet对象中的Tables属性中遍历所有的表foreach (DataTable dataTable in dataSet.Tables){dataTableDic.Add(dataTable.TableName, dataTable);}return dataTableDic;}}}//读取某个表转为Listpublic List<Person> GetPersonList(Dictionary<string, DataTable> excelDic){var personList = new List<Person>();DataTable t = excelDic["你的表名"];//索引器填表名拿到表for (int i = 0; i < t.Rows.Count; i++)//Rows属性代表所有行{Person person = new Person();//Rows[i]拿到具体的行,第一行被忽略,因为上面使用了ExcelDataSetConfiguration//Rows[i][0]代表i行第0个元素,但是类型是objperson.name = t.Rows[i][0].ToString();person.gender = int.Parse(t.Rows[i][1].ToString());person.age = int.Parse(t.Rows[i][2].ToString());person.name = t.Rows[i][3].ToString();personList.Add(person);}return personList;}}}
注意:
如果你直接使用我上述的做法,可能会遇到一个1252编码问题,细致的说就是编辑器环境正常,但是Unity打了包就无法正常读取Excel了,这个库读取Excel需要能支持1252编码的组件,但是这个组件Unity编辑器环境有,但是打包环境没有(应该是为了更轻量,剔除了),所以我将其做成了一个编辑器工具,就是在编辑器环境时将Excel数据转成ScriptObject,
就像这样,这是Unity原生的,就不会出任何问题,而且我制作的非常方便,稍作配置就能一键生成,但是还有一个不完美的地方就是:譬如你可以在steamingAssets目录下放入Excel,如果能直接读取,打包之后可以很方便的直接替换Excel,但是我这里因为制成了ScriptObject,所以这个灵活性就没有了.
如果你确实需要这个灵活性,那么请阅读官方的这一段
但是这需要带入一些依赖.
git中找到文件夹1252问题,将dll都放到Plugins下,查看Example脚本解决这个问题.
如果你使用我的转化为ScriptObject的方案,那么直接删除1252文件夹.否则你可以使用上面的Api来直接读取Excel,但是不要忘了将1252文件夹下的Dll导入Plugins,再添加这句注册代码:System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);.
personTool: 个人开发的小功能,每个文件夹的功能能做到开箱即用.
这个工具我已经封装好了.
下载后进入ExcelDataReader目录.将里面的内容拷贝到一个空的项目中,推荐Unity版本在2021.3.37f1c1或者更高.
如果编译没出问题,你会发现
Tools下面出现一个自动生成的按钮.
点击会出现这样的窗口,先点击第一个按钮,这会生成对应的类文件,等待编译.然后点击第二个按钮,就会生成ScriptObject了.
如果你需要迁移到别的工程,将脚本和ScriptObject都复制过去.
下面可以查看我第二篇文章.
在Unity环境中读取Excel配置文件(进阶)_unity读取excel文件-CSDN博客
你可以简单了解下原理