〇30 秒看懂整条链路
策划写 Excel → 工具生成"代码 + 数据" → 业务读表。就这三步。
四行结构 + 一键导出 + 一行加载
① 写 Excel(每张工作表 = 一张表)
第 1 行:字段名 ID | Name | Quality
第 2 行:类型 int | string | int
第 3 行:描述 英雄ID | 英雄名 | 品质
第 4 行起:数据 1001 | 亚瑟 | 3
② Unity 菜单 Revolution.Tools / 配置表 / 导表工具 → 把 Excel 拖进窗口 → [导出]
③ 业务就这么读:
await RevDataTableManager.LoadAsync<HeroTable>();
HeroTable.Instance.FindByKey(1001, out var hero); // 拿到 1001 这行
没有第 4 步。表的读写都走资源系统(表就是资源),所以打包、热更、分包与其它资源一套规则。
一两个版本怎么选
两个版本读同一套 Excel 规则、生成逐字节相同的代码与数据(除了文件头里的生成时间)—— 团队里混着用也不会产生无意义的 diff。
| Unity 编辑器版(推荐) | WPF 版 |
| 打开方式 | Unity 菜单 Revolution.Tools / 配置表 / 导表工具 | 独立程序(Revolution.ExcelTool,需 .NET 8 桌面运行时) |
| 要不要开 Unity | 要 | 不要(策划机器上没装 Unity 时用它) |
| 输出位置 | 自动:代码 → Assets/Revolution/Generation,数据 → <资源根目录>/Data | 手选三个目录 |
| 产物进工程 | 直接写进工程,自动导入 | 选工程里的目录,或手动拷贝 |
| Excel 开着能不能读 | 能 | 不能(要先关 Excel) |
| 改完 Excel | 窗口开着会自动重读,并标出哪些表有改动 | 手动点「读取」 |
| 生成映射 / AB 标记 | 新增 / 删除表后自动生成映射;数据没标 AB 包会提示并一键标记 | 回 RevAB 打包工具手动点「仅生成映射」 |
| 只写变了的文件 | 是(数据变了、代码没变 → 不触发脚本编译) | 否(每次全部重写) |
| CI | -executeMethod Revolution.Editor.ExcelTool.RevExcelCI.Export | — |
二Unity 编辑器版(推荐)
2.1 第一次用:三步
- 菜单
Revolution.Tools / 配置表 / 导表工具 打开窗口;
- 把
.xlsx(或装着 .xlsx 的文件夹)拖进窗口,或点「选择 Excel 文件… / 选择文件夹…」
(想先试试:点「用仓库里的样例表试试」,加载 Revolution.Demo/ExcelTool/Excel);
- 左边确认每张表都是 ✔,点右上角的 「导出 N 张表」(快捷键
Ctrl/Cmd + Enter)。
- 只改了数值、没动表结构 → 点旁边的 「仅数据」:只重新生成数据 txt,一个代码文件都不碰、不会触发脚本编译;
- 改了表结构(加字段 / 改类型 / 增删表)→ 用主按钮「导出」(代码 + 数据按需一起处理)。
以后改完 Excel、回到 Unity,窗口会自动重读并标出哪些表变了,再点一次导出就行。
不想开窗口:菜单 Revolution.Tools / 配置表 / 快速导出(用上次的 Excel 源) 一步导完(遇到错误才打开窗口给你看)。
2.2 界面
┌ 工具栏:来源 ▾ · 添加文件 · 添加文件夹 · 重新读取(F5)··················· 自动重读 · 规则 ┐
├ 概览:1 个工作簿 · 4 张表可导出 · 共 18 条数据 [ 导出 4 张表 ][仅数据][▾] ┤
│ ● 有 2 个文件待更新:1 张表的数据 │
├ ▸ 输出:代码 → Assets/Revolution/Generation 数据 → Assets/GameRes/Data AB 包 → data ┤
├───────────────┬──────────────────────────────────────────────────────┤
│ 表列表 │ Hero → Hero / HeroTable [在 Excel 中打开][定位数据文件] │
│ DemoConfig.xlsx │ 问题列表(每条带「定位」,跳到预览里的那一行) │
│ ✔ Hero ● │ [数据预览(5 行)][字段(9)] 🔍 搜索 │
│ ✔ Item │ 行 │ ★ ID │ Name │ Quality │ … ← 表头第二行是类型 · 描述 │
│ ✖ Skill 2 个错误│ 4 │ 1001 │ 亚瑟 │ 3 │ … ← 运行时解析不了的单元格会标红 / 黄 │
├───────────────┴──────────────────────────────────────────────────────┤
│ [导出结果][日志] 写了哪些文件、哪些没变;AB 标记 / 资源映射 / 旧数据文件 —— 要处理的都带按钮 │
└────────────────────────────────────────────────────────────────────────┘
| 标记 | 意思 |
| ✔ / ⚠ / ✖ | 能导出 / 有警告(能导出)/ 有错误(导出时跳过这张表,其余照常导出) |
| 灰色「忽略」 | 空白工作表,或工作表名以 # 开头(备注页)—— 不导出、也不算错 |
| 新 | 还没导出过这张表 |
| ● | Excel 里的数据和已导出的不一样,需要重新导出 |
- 表列表:双击 = 用 Excel 打开所在工作簿;右键可「定位数据文件」「复制加载代码」。
- 数据预览:显示全部行(不截断),点表头排序,右键复制行(制表符分隔,可直接粘回 Excel)。
红底 = int / float 写错(运行时会变成 0),黄底 = bool 认不出(运行时会变成 false)。
- 字段:每个字段对应的 C# 字段名与类型,以及这张表的加载示例代码。
2.3 输出位置(点「▸ 输出」展开)
| 设置 | 默认 | 说明 |
| 代码目录 | Assets/Revolution/Generation | 框架自带的 Generation 程序集(已引用 Revolution.Runtime,业务直接能用)。选到 Editor 文件夹 / 没引用运行时的程序集里会当场报错(否则会编译不过,或打包后没有这些类) |
| 数据目录 | 跟随资源根目录:<资源根目录>/Data | 运行时按逻辑路径 Data/<表名> 从资源根目录读,放别处会提示"运行时读不到"。资源根目录在 RevAB 打包工具里设置 |
| AB 包 | — | 数据目录没有 AB 标记时显示「未标记」+「标记…」按钮:给整个数据目录标一个包,以后新增的表也自动进包 |
| 新增 / 删除表后自动生成资源映射 | 开 | 等同于 RevAB 打包工具的「仅生成映射」;资源校验有错误时不生成,并在导出结果里说明 |
| 高级 | — | 容器类单独目录、两个代码文件名 |
设置存在哪
输出位置是团队共享的(ProjectSettings/RevExcelToolSettings.asset,进版本库,全队导到同一个地方);
Excel 来源是每个人自己的(UserSettings/RevExcelTool.asset,不进版本库,每人的 Excel 路径可以不同)。
2.4 导出时它会替你把关
| 情况 | 行为 |
| 某张表有错 | 跳过这张表并点名,其余照常导出(和 WPF 版一样) |
| 所有文件都没变 | 按钮显示「导出(已是最新)」,点了也不写文件 |
| 只有数据变了 | 只写那几个 txt,不触发脚本编译(智能判断代码没动就不碰;想显式跳过代码就用「仅数据」) |
| 手动切换导出模式 | 「仅数据」按钮:只写数据 txt、代码一个不碰;▾ 菜单里另有「全量生成代码和数据(强制重写全部文件)」与「仅生成数据文件(强制重写全部 txt)」(强制版连内容没变的文件也重写) |
| 上次导出过的表这次不在来源里 | 先弹框确认:继续导出会从代码里删掉它们(业务还在引用就会编译不过) |
| 数据目录里有表已经不存在的旧 txt | 导出结果里列出,可一键删除 |
两张表类名冲突、表名与框架类型重名(如 RevDataTable)、数据文件名只差大小写 | 报错,不写任何文件 |
字段 hp 和 HP(生成的 C# 名相同)、字段名与表名相同 | 这张表报错(生成出来会编译不过) |
2.5 CI / 批处理
Unity.exe -quit -batchmode -projectPath <工程> ^
-executeMethod Revolution.Editor.ExcelTool.RevExcelCI.Export ^
-excelSource D:\Tables ^
-logFile export.log
-excelSource 可以写多个(或用 ; 分隔);不写就用本机设置里的来源。
任何一张表有错都返回退出码 1(编辑器里是跳过坏表,流水线上要让人看到),成功返回 0。
三Excel 该怎么写(唯一的契约)
| 行 | 内容 | 说明 |
| 第 1 行 | 字段名 | 要能当 C# 字段名 |
| 第 2 行 | 字段类型 | 只支持 int / float / string / bool |
| 第 3 行 | 字段描述 | 只进代码注释与 txt 表头,不参与数据 |
| 第 4 行起 | 数据 | 一行一条记录 |
两条最容易记住的规则
① 第一个字段(第一列)就是主键,不需要额外标记;
② 一个工作表 = 一张表:工作表名 Hero → 生成 Hero 数据结构 + HeroTable 容器。
一个能直接抄的例子(工作表名:Hero)
| A | B | C | D | E | F | G | H |
| 1 | ID | Name | Quality | Attack | Hp | MoveSpeed | IsRanged | Camp |
| 2 | int | string | int | float | int | float | bool | string |
| 3 | 英雄ID | 英雄名 | 品质 | 攻击力 | 生命值 | 移动速度 | 是否远程 | 所属阵营 |
| 4 | 1001 | 亚瑟 | 3 | 120.5 | 3600 | 3.8 | false | 秩序 |
| 5 | 1002 | 妲己 | 3 | 95 | 3200 | 3.6 | true | 无序 |
列与行的处理规则(省得踩坑)
| 情况 | 行为 |
| 第 1 行该列留空 | 整列忽略(右侧常见的空列不用管) |
列名以 # 开头 | 视为策划备注列,整列忽略 |
| 某行少填了几列 | 按空值处理(列数以第 1 行为准) |
| 整行为空 | 跳过 |
该行第一列以 # 开头 | 整行当作注释跳过(表尾写备注很方便) |
工作表名以 # 开头 / 整张工作表是空的 | 不导出(编辑器版显示为灰色「忽略」;WPF 版会标成有错误再跳过,结果一样) |
| 主键列为空 / 主键重复 | 报错(写清是第几行;编辑器版可一键定位到那一行) |
| int / float 列填了非数字 | 报错(运行时会变成 0) |
| bool 列填了认不出的值(如「对」「x」) | 编辑器版警告(运行时会当成 false);认得的写法:true/false、1/0、是/否、yes/no、y/n |
可运行的样例
Revolution.Demo\ExcelTool\Excel\DemoConfig.xlsx —— 4 张表(Hero / Item / Skill / Buff,含 string 主键的示例)可以直接对着抄。
编辑器版的空窗口里点「用仓库里的样例表试试」就会加载它。
四WPF 版:导出 → 接进 Unity
不开 Unity 也能导(比如策划机器上没装 Unity)。
| 项 | 说明 |
| 运行环境 | .NET 8 桌面运行时(Windows)。工程目标是 net8.0-windows |
| 启动(开发期) | cd Revolution.ExcelTool → dotnet run |
| 启动(给策划用) | 直接跑 Revolution.ExcelTool\bin\Debug\net8.0-windows\Revolution.ExcelTool.exe;给别人就用 dotnet publish -c Release 把产物目录拷走(零第三方依赖) |
| 首次启动 | 三个输出目录要手选一次,之后会记住(存在本机 APPDATA 里) |
界面从上到下:① Excel 数据源 [选择文件][选择目录][读取] → ② 表列表 → ③ 表结构预览(前 50 行)→ ④ 输出路径(三个目录)→ ⑤ [仅生成数据] [全量生成(代码+数据)] → ⑥ 日志。
先「读取」再「导出」;读取前要先关掉 Excel(WPF 版打不开 Excel 正在编辑的文件)。
两个导出按钮对应两种场景:只改了数值 → 「仅生成数据」(只写 txt,一个代码文件都不碰);改了表结构 → 「全量生成(代码+数据)」。
| 输出 | 放到哪 | 说明 |
| 数据结构类 + 容器类 | Assets/Revolution/Generation/ | C# 代码,进版本库(生成物,别手改) |
| TXT 数据文件 | 资源根目录下的 Data/(如 Assets/GameRes/Data/) | 它是资源,走资源系统加载 / 打包 / 热更 |
Excel 改动→
WPF 导出→
产物进工程→
Unity 自动导入→
生成映射(RevAB)→
运行期 LoadAsync 读表
WPF 版别漏掉"生成映射"
新增了表(新的 txt 是新资源)时,在 AB 模式(真机 / 打包后)下必须回 RevAB 打包工具点一次「仅生成映射」,
否则运行期报"找不到映射"。编辑器直读模式下不需要。编辑器版会自动做这一步。
五业务侧:一行读表(运行时 API)
入口是 RevDataTableManager;生成的 XxxTable.Instance 就是它的快捷方式。
| 我想… | 这么写 |
| 加载一张表(异步,推荐) | await RevDataTableManager.LoadAsync<HeroTable>() |
| 加载(同步) | HeroTable t = RevDataTableManager.Load<HeroTable>() |
| 拿已加载的表 | RevDataTableManager.Get<HeroTable>() |
| 拿不到就算了 | RevDataTableManager.TryGet<HeroTable>(out var t) |
| 判断是否已加载 | RevDataTableManager.IsLoaded<HeroTable>() |
| 卸载 / 全部卸载 | RevDataTableManager.Unload<HeroTable>() · UnloadAll() |
| 看加载了哪些 | RevDataTableManager.Tables · RevDataTableManager.LoadedCount |
| 按主键查一行 | HeroTable.Instance.FindByKey(1001, out var hero) |
为什么"表 = 资源"很重要
表跟着资源体系走:打包、分包、热更、卸载都用同一套;表大了还能单独分一个包(配置组 RevResGroup.Config)。
六新手最容易踩的坑
| 坑 | 正确做法 |
| ① 主键留空 / 重复 | 第一个字段必须每行都有值且唯一(工具会报错,写着行号) |
② 用了不支持的类型(如 double/long) | 只有 int/float/string/bool;需要别的就在业务里转换 |
| ③ 改了工作表名,业务里没跟着改 | 表名 = 工作表名,生成的类名跟着变 → 改名后要重新编译(编译期就报错,不会静默)。编辑器版导出前会提示"会移除表" |
| ④ 改了 Excel 没重新导出 | 数据是快照:Excel 改动必须重导一次。编辑器版窗口开着时会自动重读,并在表名后标 ● 提醒你 |
| ⑤ 直接改生成的 C# 文件 | 那是生成物,下次导出会被覆盖 → 要改结构就改 Excel,要改逻辑就写在业务层 |
| ⑥ 数据文件没有 AB 标记 | 编辑器里读得到、真机读不到。编辑器版导出后会提示,点「标记数据目录…」给整个数据目录标一个包 |
最坑的一条:忘了"生成映射"
编辑器里读表好好的,打包到真机就报找不到 —— 十有八九是漏了 RevAB 的「仅生成映射」。
编辑器版在新增 / 删除表后会自动生成;用 WPF 版的话,把这一步固化到打包流程里。