尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

jynew Mod 配置系统实战指南:从 Excel 配置表到 Lua/C 双端读取

jynew Mod 配置系统实战指南:从 Excel 配置表到 Lua/C 双端读取 jynew Mod 配置系统实战指南从 Excel 配置表到 Lua/C# 双端读取【免费下载链接】jynewJinYongLegend-like RPG Game Framework with full Modding support and 10 hours playable samples of game.项目地址: https://gitcode.com/GitHub_Trending/jy/jynewjynew金庸群侠传 3D 重制版一个带完整 Mod 支持与 10 小时可玩示例内容的 RPG 游戏框架中游戏内所有数值、剧情、物品、角色等数据都以「Excel 配置表」为源头进行管理。本篇技术指南以jyx2/Assets/Mods/JYX2/Configs/README.md为骨架系统讲解 jynew 配置系统的完整工作流如何编写 Excel 配置表、如何理解LuaConfigGen标记与字段类型体系、如何在编辑器里一键生成游戏内实际使用的 Lua 配置表以及如何在 Lua 脚本与 C# 侧分别高效读取配置数据。读完本文你将能够独立为 jynew 的任意 Mod 新增或修改配置表并掌握底层生成与读取的实现原理。一、配置系统的整体工作流Excel 为源、Lua 为运行时、C# 桥接jynew 的配置管理遵循一条非常清晰的单向数据流编辑阶段使用 Excel 编写配置表文件放在 Mod 目录的Configs文件夹中例如 jyx2/Assets/Mods/JYX2/Configs 目录下的人物.xlsx、物品.xlsx、武功.xlsx、战斗.xlsx、场景.xlsx、加成.xlsx、小宝商店.xlsx、游戏设置.xlsx等。生成阶段在 Unity 编辑器中启动游戏时配置会被自动读取并生成游戏内使用的 Lua 配置表也可以手动刷新——点击 Mod 根目录中的ModSetting文件即 jyx2/Assets/Mods/JYX2/ModSetting.asset在右侧Inspector面板中点击「生成配置表」按钮即可重新生成 Lua 配置表。运行阶段生成的 Lua 配置表在游戏初始化时被读入全局 Lua 表Jyx2.ConfigMgrLua 脚本直接访问C# 侧则通过 XLua 的桥接接口jyx2/Assets/Scripts/LuaCore/Jyx2LuaToCsBridge.cs以强类型接口方式读取。这里有一条必须遵守的红线Lua 配置表才是游戏实际使用的配置表但绝对不要手动修改它。任何对 Lua 配置表的直接改动都会在下次启动游戏时被重新生成覆盖同时 Lua 配置表也无法上传到项目的 Git 仓库中会被忽略。想要修改配置一律修改对应的 Excel 文件再触发重新生成。二、Excel 配置表格式规范配置表使用 Excel 文件编写文件名没有硬性要求但建议使用容易理解的名字仓库内即使用中文文件名如人物.xlsx。表格的列结构是固定约定的以下面的示例表为例| Excel | A | B | C | |--|--|--|--| | 1 | LuaConfigGen | ConfigName | | | 2 | 代号 | 名称 | 更多字段 | | 3 | L_number | L_string | L_number[] | | 4 | Id | Name | Other | | 5 | 1 | 胡斐 | 1,3,5 |各区域职责如下A1 单元格固定的标记值LuaConfigGen用来标明这个表格是一个配置表。如果A1中的值不是LuaConfigGen该 Excel 将被直接忽略。B2 单元格填写配置表的名称。可以在游戏中使用这个名称访问该配置表。例如B2的值为Character则可以在 Lua 脚本中使用Jyx2.ConfigMgr.Character访问该配置表。第 24 行字段设置区。第 2 行为每个字段的中文解释第 3 行指定字段的值类型第 4 行为字段的名字。第 5 行起具体数据区每一行表示一条数据。2.1 字段的解释第 2 行第 2 行目前只是为了让 Excel 表容易理解而写的注释不会对配置表的功能产生任何影响。它是纯文档性质的可以放心填写中文说明。2.2 字段数据类型第 3 行数据类型分为基础型、复合型、列表型三种基础型数字L_number字符串L_string布尔L_boolean复合型将基础型用,隔开例如L_number,L_stringL_number,L_boolean,L_number说明单独使用复合型没有意义不如拆开变成几个基础型用起来方便复合型主要用于配合列表使用。列表型基础型或复合型加上[]用来表示由多个该类型数据组成的列表例如L_number[]一个数字列表L_number,L_string[]一个复合型列表列表中每个元素都是由一个数字和一个字符串组成的复合型数据2.3 字段名称第 4 行使用拉丁字符表示可以在游戏中使用该名称访问这个字段。例如在 Lua 中使用Jyx2.ConfigMgr.Character[0].Name可获取配置表Character中第 1 条数据的Name字段的值。如果某个字段的名称是空白的或者以#开头那么该字段就会被忽略游戏中将无法获取该字段的任何值。复合型列表字段嵌套表格如果一个字段的数据类型是复合型列表为了访问方便应当为字段中复合型数据的每一个元素起一个名字。以配置表武功中的字段为例Levels-Attack,SelectRange,AttackRange,AddMp,KillMp这是一个复合型列表字段的名称对应的数据类型为L_number,L_number,L_number,L_number,L_number[]其中Levels是字段的实际名称Attack、SelectRange、AttackRange、AddMp、KillMp分别是Levels中元素的五个属性的名称。也就是说Levels实际上是一个嵌套进来的子表其下有名为Attack、SelectRange等五个子字段。使用时-- 将表中 Id 为 0 的数据的 Levels 字段存储到 level0 中 local level0 Jyx2.ConfigMgr.Skill[0].Levels -- level0 是一个新的表访问其中第一个元素的 Attack 字段 local atk level0[1].Attack注意如果只使用Levels作为字段名称而不给元素命名那么例子中的level0[1].Attack依然可以用level0[1][1]访问但会严重缺乏可读性因此强烈建议为复合型列表元素命名。2.4 数据区第 5 行起每一行是一条数据Id字段的值可以用来访问这条数据。例如Jyx2.ConfigMgr.Character[233]可以读取配置表Character中Id为233的那条数据。如果一条数据的Id字段是空白的或者以#开头那么这条数据就会被忽略。复合型字段的值使用,分隔复合型值的每一个元素。例如13,abc是一个L_number,L_string类型的值。列表型字段的值使用|分隔列表中的每一个元素。例如13|14|16是一个L_number[]类型的值13,abc|14,ef是一个L_number,L_string[]类型的值这一套「,分隔复合元素、|分隔列表元素、#注释、Id定位」的约定构成了 jynew 配置表数据区的完整语法。三、在 Lua 侧读取配置表生成的配置表会在游戏初始化时被读入Jyx2.ConfigMgr这个全局 Lua 表。在 Lua 脚本中使用如下代码即可访问写法可以自由组合-- 可以直接调用 local roleName Jyx2.ConfigMgr.Character[2].Name -- 但推荐先获取配置表模块以后用起来会比较方便 local configMgr Jyx2:GetModule(ConfigMgr) -- 获取名为 Character 的配置表下面几种方式都可以 local cfg1 configMgr:GetConfig(Character) local cfg2 configMgr[Character] local cfg3 configMgr.Character -- 读取名为 Character 的配置表中 Id 为 123 的一条数据 local item1 cfg1[123] local item2 configMgr.Character[123] local item3 configMgr:GetItem(Character, 123) -- 读取名为 Name 的字段 local value1 item1[Name] local value2 item1.Name local value3 configMgr.Character[123].Name -- 注意尽量不要修改 Lua 配置表中的值容易引起其他读取该配置的模块的异常值得注意的细节Jyx2:GetModule(ConfigMgr)这种通过模块管理器获取的方式与Jyx2.ConfigMgr全局访问是等价的前者更便于代码组织。GetConfig(名称)、configMgr[名称]、configMgr.名称三种取表方式结果相同cfg1[123]、configMgr.Character[123]、GetItem(Character, 123)三种取行方式也等价。字段既可以通过item1[Name]字符串索引访问也可以通过item1.Name点语法访问。官方明确警告尽量不要修改 Lua 配置表中的值否则容易引起其他读取该配置的模块出现异常。配置表应当被当作只读数据源使用。仓库的 jyx2/Assets/Mods/JYX2/Lua/modentry.lua 中就有这种用法的真实示例以注释形式给出--[[ 测试mod端LuaScripts功能 local configMgr Jyx2:GetModule(ConfigMgr) local modTest Jyx2:GetModule(ModTest) print(configMgr.Character[122].Name) modTest:PrintTest()]]3.1 为 Lua 配置表增加功能性函数如果想让配置表中的每条数据「看起来像 C# 中的对象」拥有自己的成员函数可以建立一个Jyx2ConfigMgr/MapHelper之类的模块在其中定义相关函数。例如为名称为Map的配置表定义GetShowName函数后在 Lua 脚本中可以像对象的成员函数一样调用Jyx2.ConfigMgr.Map[1]:GetShowName()即访问Map表中Id为 1 的那条数据的GetShowName函数。具体格式参考仓库中的MapHelper和ItemHelper文件即可。四、在 C# 侧读取配置表Lua→C# 桥接C# 侧可以使用接口来访问 Lua 配置表按照 Lua 侧的数据结果写一个接口按照 XLua 的说明添加[CSharpCallLua]标签重新生成代码即可。具体定义参考 jyx2/Assets/Scripts/LuaCore/Jyx2LuaToCsBridge.cs。从源码可以看到jynew 已经为各个配置表定义了相应接口该文件第 21 行附近即为[CSharpCallLua]接口声明的示例如LBattleConfig其属性Id、Name、MapScene、Exp、Music、TeamMates等与 Excel 配置表的字段一一对应。例如 Item 表映射到了字典Jyx2.LuaToCsBridge.ItemTable可以通过Jyx2.LuaToCsBridge.ItemTable[1]访问 Item 表中 Id 为 1 的那条数据。从 jyx2/Assets/Scripts/LuaCore/Jyx2LuaToCsBridge.cs 的LuaConfigToCsInit实现可以印证底层的读取机制C# 侧通过 XLua 的LEnv.Global.GetInPathT(...)直接从全局表Jyx2.ConfigMgr中取出各张配置表并映射为强类型字典例如// 从 Lua 全局表读取各配置表并转为 C# 字典 Liststring ConfigList LEnv.Global.GetInPathListstring(Jyx2.ConfigMgr.ConfigList); CharacterTable LEnv.Global.GetInPathDictionaryint, LRoleConfig(Jyx2.ConfigMgr.Character); SkillTable LEnv.Global.GetInPathDictionaryint, LSkillConfig(Jyx2.ConfigMgr.Skill); ItemTable LEnv.Global.GetInPathDictionaryint, LItemConfig(Jyx2.ConfigMgr.Item); BattleTable LEnv.Global.GetInPathDictionaryint, LBattleConfig(Jyx2.ConfigMgr.Battle); MapTable LEnv.Global.GetInPathDictionaryint, LMapConfig(Jyx2.ConfigMgr.Map); ShopTable LEnv.Global.GetInPathDictionaryint, LShopConfig(Jyx2.ConfigMgr.Shop); SettingsTable LEnv.Global.GetInPathDictionaryint, LSettingsConfig(Jyx2.ConfigMgr.Settings);这解释了为什么 C# 侧能像查字典一样用Id键直接命中数据Lua 配置表本身是以Id为键的表桥接时被原样转换成了Dictionaryint, T。需要注意的边界修改 C# 侧的接口需要重新编译游戏框架因此在 Mod 中难以实现。官方在文档中明确说明将来会将一部分游戏功能改为 Lua 侧实现这样 Mod 可以在 Lua 侧对配置表进行更大的修改。也就是说目前 Mod 作者扩展配置表的能力边界主要在 Excel Lua 侧C# 接口属于框架层能力。五、实际使用场景与配置表一览在 jynew 主 Modjyx2/Assets/Mods/JYX2/Configs中配置表按业务划分为多张 Excel人物.xlsxCharacter角色/人物属性数据物品.xlsxItem道具物品数据武功.xlsxSkill武功技能数据其中即包含上文示例的Levels复合型列表字段升级属性战斗.xlsxBattle战斗场景配置场景.xlsxMap地图场景配置加成.xlsxExtra附加加成数据小宝商店.xlsxShop商店商品数据游戏设置.xlsxSettings游戏全局设置这些 Excel 表与 Jyx2LuaToCsBridge.cs 中读取的Character、Skill、Item、Battle、Map、Shop、Settings等字典一一对应形成「Excel → Lua 配置表 → C# 强类型字典」的完整链路。六、常见问题与最佳实践小结改了 Excel 但游戏里没生效检查A1是否仍为LuaConfigGen被忽略的表格不会生成配置确认后回到 Unity 编辑器点击ModSetting的「生成配置表」按钮重新生成或重启游戏触发自动生成。字段读不到值检查字段名是否为空或以#开头会被忽略检查字段类型声明与实际数据是否匹配如列表值必须用|分隔。数据行不生效检查该行Id是否为空或以#开头会被忽略。复合型列表可读性差务必为复合型列表的每个元素命名Levels-Attack,SelectRange,...写法否则只能通过[1][1]式下标访问。不要改 Lua 配置表Lua 配置表是生成产物改动会被覆盖、无法入库且可能破坏其他模块。C# 侧扩展受限新增 C# 接口需重编译框架Mod 场景下优先在 Lua 侧做扩展如通过MapHelper、ItemHelper类模块为数据附加函数。七、进一步阅读配置表说明原文jyx2/Assets/Mods/JYX2/Configs/README.md实际配置表示例Exceljyx2/Assets/Mods/JYX2/ConfigsC# 侧桥接实现jyx2/Assets/Scripts/LuaCore/Jyx2LuaToCsBridge.csMod 初始化与配置读取示例jyx2/Assets/Mods/JYX2/Lua/modentry.luaMod 设置资产触发配置表生成jyx2/Assets/Mods/JYX2/ModSetting.asset【免费下载链接】jynewJinYongLegend-like RPG Game Framework with full Modding support and 10 hours playable samples of game.项目地址: https://gitcode.com/GitHub_Trending/jy/jynew创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表