将 Excel 表格导入 Unity 项目

在游戏开发过程中,策划往往会在 Excel 中配置游戏数据,比如物品、技能和 NPC 的属性等。因此如何将 Excel 里的数据导入到游戏中是游戏开发的重要课题。

朴实的方法:另存为 csv

比较朴实的方法是将 Excel 文件另存为 csv 文件,然后程序员写代码解析 csv 文件。可以将 csv 转换成游戏程序可以识别的格式,比如 Unity 的 ScriptableObject 或是一个硬编码的 C# 数组,即一份 cs 文件。甚至也可以在游戏运行时才读取 csv 文件。

这种方法的优点是要解析的文件格式(即 csv)很简单,不用引入第三方库,程序逻辑也就比较简单。缺点是每次编辑完 Excel 文件还要另存为 csv ,这对日常工作来说颇为繁琐,而且每次“另存为”也只能导出一份 Excel 文件,无法对多份文件执行批量导出。

我的上一家游戏公司的解决方案

在我的上一份游戏开发工作中,公司有一套复杂的导出工具。那套工具在 Excel 界面中添加了一个按钮,点击一下就可以在 Excel 打开的状态下将表格里的数据直接导出为硬编码的 C# 数组。那套工具也提供了 bat 脚本用于批量导出。可是那套工具也有好些缺点:

  • 内部构成太复杂。全套工具内部包含 vba 脚本、bat 脚本、一些闭源的 exe,以及许多 python 和 lua 脚本。这就意味着维护和改进成本很高,而且由于有闭源 exe 的存在,未来可能还会遇到无法排查的问题。
  • 只能在 Windows 上使用,可我现在经常要在 Mac 上开发游戏。
  • 导出的文件直接就是 cs 源码文件。这会给未来的热更新带来很大麻烦。在上一家游戏公司工作时我们倒是解决了 C# 代码的热更新问题,但内部机制非常复杂。
  • 每增加一张 Excel 表格,程序员就要写一份 lua 脚本文件用于解释表格的格式——尽管这份 lua 文件的内容很简单。后来有同事做过改进,免去了这份 lua 文件的必要性,但是对数据表的格式就有更多要求。不过每张数据表需要写一份 lua 文件只是个很小的可以忽略的缺点。

因此,我没有采用上一家游戏公司的解决方案。

通用方案:ExcelDataReader

我曾考虑使用微软提供的 .NET Office 编程接口实现一个较为通用的解决方案。这里我所说的“通用”是指解决方案不仅可用于 Unity 项目,也可用于其它引擎,这样也便于生成服务端可自然读入的数据脚本。在这个过程中我找到了一个开源的轻量级的跨平台 C# 库—— ExcelDataReader,可用于读取 Excel 文件中的表格数据。我把这个库下载下来试验过,的确很好用,接口也很简单。

唯一的问题在于,这个库依赖 System.Data.dll(即便是不带 DataSet 接口的 ExcelDataReader)。Unity 引擎倒是携带了 System.Data.dll,但是一个干净的 Unity 项目却并不包含这个 dll。因此如果想在 Unity 项目的代码中用这个库读出 Excel 数据,再用 Unity 接口将数据保存为 ScriptableObject 的话,就要将 System.Data.dll 拷贝进 Unity 项目的 Assets 文件夹中。这并不是我喜欢的方式。一方面这不符合我的工程审美;另一方面万一 dll 需要升级,则要手动维护 dll 的版本,并且要在每个 Unity 项目中都手工维护这个信息。

如果不想维护 System.Data.dll 的话,还有另一个办法,就是在 Unity 项目之外维护一个单独的 .NET 命令行项目。这个 .NET 项目用 ExcelDataReader 读入 Excel 数据,然后输出 Unity 项目可以识别的格式。可以输出 ScriptableObject。但是这样就需要研究并理解 ScriptableObject 的内部格式,无法利用 Unity 已经提供的 ScriptableObject 接口。也可以输出 csv,然后由 Unity 项目的代码读入 csv,再转换为 ScriptableObject。但这就将数据的导入过程分成了两步,并不是完美的一次单击就自动到位的全自动化方案。

Unity方案:Unity-QuickSheet

这是我最后实际采用,并在现所属的游戏公司开始推行的解决方案。和 ExcelDataReader 相比,它有如下优点:

  • 因为这是专门用于 Unity 项目的插件,所以可以在 Unity 项目中直接使用,不必再引入第三方库。
  • 这个插件已经提供了从 Excel 文件生成 C# 类定义(cs 文件)以及 ScriptableObject asset 文件的完整工作流。只要点几下按钮就可以导入数据,全程不用写一行代码——这也是作者亲自宣传标榜的优点。因此与其说这是一个库,不如说它就是一个工具。
  • 该插件除了能读取 Excel 文件,还可以读取线上的 Google Spreadsheets,而我们公司大量使用了 Google Spreadsheets。

有点美中不足的是,这个插件没有提供批量导入功能。另外生成类定义的时候变量命名有点问题,无法生成 fieldName 或是 PropertyName 这样的驼峰命名。不过因为内部代码并不复杂,我完全可以自己修改源代码从而改进这个插件。实际上我也已经从原作者的库 fork 了一份我自己的库:https://github.com/zzxiang/Unity-QuickSheet。我在这个 fork 的 mokagames 分支中已经修复了变量命名的问题和一些小瑕疵,未来也打算加入批量导入功能。

本文在我的独立博客上的地址:http://zxtechart.com/2018/04/29/unity-excel/

你可能感兴趣的:(游戏开发,Unity)