ET5.0 配置Excel

使用方式:

写表

打开 Excel 目录下的 UnitConfig.xlsx
ET5.0 配置Excel
A1:根据该单元格内是否存在 AppType.ClientH 区别生成的是客户端还是服务器的配置
C3:从这里开始读取数据
读写规则:
第3行:该行为注释行内容不读取, # 开头该列不读取, s 开头该字段服务器专用
第4行:该行内容作为字段的名称,不可为空
第5行:该行内容作为字段的类型,不可为空
第6行及以下:配置的数据

嵌套

当你需要在列表里面嵌套的时候,我觉得你应该重新审视一下你的逻辑
如果你实在不想考虑了,一定要嵌套!那么你可以再开一个表,这个表就是嵌套的数据,然后在需要嵌套的表里面填写该表的数据的ID!
需要嵌套的表:
ET5.0 配置Excel
被嵌套的表:
ET5.0 配置Excel
大约这么去访问,就可以得到完整数据,对扩展也友好:

var testConfig = Game.Scene.GetComponent<ConfigComponent>().Get(typeof(TestConfig),1001) as TestConfig;
var test2 = Game.Scene.GetComponent<ConfigComponent>().Get(typeof(Test2Config), testConfig.a);

访问配置数据

// 读取 TestConfig 类型所有数据
var array =  Game.Scene.GetComponent<ConfigComponent>().GetAll(typeof(TestConfig));
foreach (TestConfig config in array)
{
	Log.Debug($"{config.a}");
}

注意事项:

id字段是不可缺少的,不能移除id字段
ET5.0 配置Excel
点击导出客户端配置或服务器配置时报一下错误,这是由于你正在使用独占模式打开Excel导致的,关闭正在修改的Excel就好
ET5.0 配置Excel
可读取字段中存在空白数据,字段数据是不允许空白的,必须写点什么
当然你觉得这很麻烦和自己的习惯不符,你也可以修改一下源码读到空白数据直接给与一个默认值之类的
但是并不赞成这么做。直接写在表上可以直接查询该值,更有利于阅读。
并且其他人阅读的时候不会疑惑这里为什么空白一片
ET5.0 配置Excel
删除了,又没有完全删除,按下delete删除了黄色列,但实际上读取的时候还是会读到,需要删除单元格才能正常读取
ET5.0 配置Excel
ET5.0 配置Excel

生成结果:

点击导出客户端配置或导出服务器配置即可
ET5.0 配置Excel
正常没有报错的情况下将会在 ET\Unity\Assets\Res\Config 文件夹生成对应的配置数据
并且在
Assets/Model/Module/Demo/Config
Assets/Hotfix/Module/Demo/Config
Server/Model/Module/Demo/Config
目录下生成配置类
ET5.0 配置Excel
ET5.0 配置Excel

模块源码:

编辑器扩展

目录:ET\Unity\Assets\Editor\ExcelExporterEditor\ExcelExporterEditor.cs
修改类生成目录,下面路径按照自己放置位置修改就行:

	private void OnGUI()
	{
		try
		{
			const string clientPath = "./Assets/Res/Config";

			if (GUILayout.Button("导出客户端配置"))
			{
				this.isClient = true;
				
				ExportAll(clientPath);
				
				ExportAllClass(@"./Assets/Model/Module/Demo/Config", "namespace ETModel\n{\n");
				ExportAllClass(@"./Assets/Hotfix/Module/Demo/Config", "using ETModel;\n\nnamespace ETHotfix\n{\n");
				
				Log.Info($"导出客户端配置完成!");
			}

			if (GUILayout.Button("导出服务端配置"))
			{
				this.isClient = false;
				
				ExportAll(ServerConfigPath);
				
				ExportAllClass(@"../Server/Model/Module/Demo/Config", "namespace ETModel\n{\n");
				
				Log.Info($"导出服务端配置完成!");
			}
        }
		catch (Exception e)
		{
			Log.Error(e);
		}
	}

扩展配置表支持的字段类型,需要支持更多类型在这里添加就可以了:

	private static string Convert(string type, string value)
	{
		switch (type)
		{
			case "int[]":
			case "int32[]":
			case "long[]":
				return $"[{value}]";
			case "string[]":
				return $"[{value}]";
			case "int":
			case "int32":
			case "int64":
			case "long":
			case "float":
			case "double":
				return value;
			case "string":
				return $"\"{value}\"";
			default:
				throw new Exception($"不支持此类型: {type}");
		}
	}

配置加载

配置组件: ConfigComponent.cs
遍历所有配置类型,BeginInit初始化后添加到缓存

		public void Load()
		{
			this.allConfig.Clear();
			List<Type> types = Game.EventSystem.GetTypes();

			foreach (Type type in types)
			{
				object[] attrs = type.GetCustomAttributes(typeof (ConfigAttribute), false);
				if (attrs.Length == 0)
				{
					continue;
				}
				
				ConfigAttribute configAttribute = attrs[0] as ConfigAttribute;
				// 只加载指定的配置
				if (!configAttribute.Type.Is(AppType.ClientH))
				{
					continue;
				}
				
				object obj = Activator.CreateInstance(type);

				ACategory iCategory = obj as ACategory;
				if (iCategory == null)
				{
					throw new Exception($"class: {type.Name} not inherit from ACategory");
				}
				iCategory.BeginInit();
				iCategory.EndInit();

				this.allConfig[iCategory.ConfigType] = iCategory;
			}
		}

配置初始化

配置每一行作为一个类数据,反序列化json后保存到字典中

		public override void BeginInit()
		{
			this.dict = new Dictionary<long, IConfig>();

			string configStr = ConfigHelper.GetText(typeof (T).Name);

			foreach (string str in configStr.Split(new[] { "\n" }, StringSplitOptions.None))
			{
				try
				{
					string str2 = str.Trim();
					if (str2 == "")
					{
						continue;
					}
					T t = ConfigHelper.ToObject<T>(str2);
					this.dict.Add(t.Id, t);
				}
				catch (Exception e)
				{
					throw new Exception($"parser json fail: {str}", e);
				}
			}
		}
上一篇:本地配置hosts快速访问GitHub


下一篇:23 个非常有用的 NodeJs 库