Unity3D高级编程:主程手记
上QQ阅读APP看书,第一时间看更新

3.2.2 让数据使用起来更加方便

使用什么形式的文件作为数据表并不重要,CSV也照样能把游戏运行得很好,因为这些技术并不能决定游戏的性能,只要我们喜欢,什么形式都可以。很多时候,我们在选定数据存储规则时,大都选择自己喜欢的方式,只要符合团队的做事风格即可,因为这能提升我们的工作效率,加快开发速度,团队不用浪费时间去适应新的规则。

数据表的关键作用是连接游戏策划设计师与其他部门,所以我们在制定数据导入/导出规则的时候需要考虑设计师的体验因素。如何让策划在配置数据表的时候能够有更好的体验就成了关键。

为什么要好用呢?只有好用才能提高效率。前面提到的自动化就是提高效率的一种方法,还有比如一键转化×××,这种形式也是提高效率的好办法。

一键转化Excel为其他格式是一个比较人性化的工具,不需要人工手动去转化,通过工具就能搞定,只要数值策划按照双方约定的规则执行即可。这能大大提高数值策划与程序员的协调性。如一个系统或一个模块需要什么数值、需要什么类型的数值、数据表建立的流程,在你们约定的填表规则上,建立、读取、转化变得轻而易举。在这种规则下,大家节省了沟通时间,彼此能默契合作,是多么高效和舒心。

只有自动化,或者只有一键转化×××的功能,还是不够。这些只是工具,我们要的是团队间,特别是部门间、不同工种间的配合顺畅无障碍。

如果只是单个表有了自动化,策划设计人员可以自由地将Excel数据转化成能让程序员读取的数据格式,但是策划设计人员一直在对数据进行变动,特别是对字段的类型、字段的名字进行调整,今天这个字段定义为ID,明天这个字段成为time,或者插入一个新的字段,删除旧的字段,或者新增一个数据表,或者删除一个旧的数据表,等等,这会让程序员很头疼,每次更改都需要及时通知程序员,即使及时收到通知,也会遇到不少麻烦。

因此我们再次强调这种规则的好用性,将单个表变为多个表的自定义配置,所有策划内容的数据表和导出规则都由策划来指定填写。

每次策划设计人员增加Excel表时,都要跟程序员说:“你帮我把这个Excel表加入自动化和一键转化×××的功能里。”程序员就需要腾出时间和精力来为策划设计人员服务。事实上,我们可以把这块工作移交出去,策划设计人员能够自定义导出哪个Excel文件,以及Excel文件里的哪个工作簿。这样策划设计人员可以自主选择和自主增加表的导出内容。

我们来看怎么做。一个可行的办法是,在程序命令中预留几个参数,参数指向某个需要导出的文件及sheet。那么在命令行里,执行这个程序且后面跟上参数就能导出数据。

但是批处理写命令行也好,shell写命令行也好,毕竟还是程序级别的。策划设计人员并不能很好地控制表中的导出内容。比如要新增一个表,或者修改某个表的文件名,或者修改导出某个表文件里的sheet,这项工作还是需要通过修改命令行来完成的,或者修改批处理文件或shell文件。但策划设计人员并不会修改,或者说这种命令形式并不直观,怎么办?

再次加入规则,让自动化和一键转化×××更加人性化。我们可以增加一个Excel表,表中填有具体要导出哪些Excel文件里的哪个sheet,这些sheet数据导出后的文件名是什么,以及生成文件后应该转移到哪个文件夹中去。这样策划设计人员在定制数据时,就可以自行决定需要用哪些Excel和sheet,做到完全由策划设计人员自行掌控。策划设计人员完全能够主导所有数据的导出工作和转移工作。

图3-1所示为策划设计人员通过配表来自定义管理Excel的导出情况,虽然这样方便了策划设计人员,但程序员的麻烦还没解决,如果策划设计人员修改了字段名,插入了新的字段,删除了旧的字段,又没有及时通知程序员,或者忘记了自己做过的事情,怎么办?彻查?不可以,效率太低,不可以让这种事情发生。

图3-1 导出配置表的自定义目录

在Excel中生成数据时自动与程序的变量对齐,就能起到校验和索引的作用,为此我们再来加一个让Excel字段名与程序对应的规则。编写一个程序,让程序生成一段代码,这段代码里变量定义的数字与每个数据表上字段名的索引对应,将每个要导出的sheet里的头行的列名作为变量名写入程序变量定义中,以方便程序在读取数据表时列名与数据表对齐,这样不仅有了读取数据表列的Key值,还无形中进行了表数据与程序索引的校验。

如图3-2所示,在role.xls文件中,sheet(工作簿)中的第一列字段为ID,第二列字段为Name,第三列字段为Age,那么通过生成程序,将表的列名自动生成为程序代码,自动生成后就有了以下格式的索引对齐方式代码:


public Class ExcelDefine
{
    public const int role_role_ID = 1;          // role表的role工作簿的ID列
    public const int role_role_Name = 2;        // role表的role工作簿的Name列
    public const int role_role_Age = 3;         // role表的role工作簿的Age列
}

// 获取名字的例子
string role_name_str =RoleTable.GetStr(ExcelDefine. role_role_Name);
int table_role_id = RoleTable.GetInt(ExcelDefine. role_role_ID);

策划设计人员在更改字段、新增字段、删除字段后,会如何呢?比如将第一列ID更改为Identifier、第二列插入School、第三列Age删除后(见图3-3),生成了如下代码:


public Class ExcelDefine
{
    public const int role_role_Identifier = 1;
    public const int role_role_School = 2;
    public const int role_role_Name = 3;
}

// 此时原来的代码就会报错
string role_name_str =RoleTable.GetStr(ExcelDefine. role_role_Name);
int table_role_id = RoleTable.GetInt(ExcelDefine. role_role_ID);

// 原来的代码应该改成
string role_name_str =RoleTable.GetStr(ExcelDefine. role_role_Name);
int table_role_id = RoleTable.GetInt(ExcelDefine. role_role_Identifier);

图3-2 示例表

图3-3 策划设计人员修改字段后

如此一来,数据表变换并转换为具体的数据工具后,原来在程序中使用的ExcelDefine.role_role_ID、ExcelDefine.role_role_Age将失效报错,而ExcelDefine.role_role_Name则自动转入读取第三列,无须修改。

有了这几段程序,程序员不再需要知道策划设计人员修改的数据是第几列,因为在编译时就会报错,提示程序员表中的哪些字段进行了修改,你只需要向策划设计人员询问具体意见即可。

到此,我们有了自动化和一键转化×××的工具,省去了不少人力,并且加入了规则,让策划设计人员完全可以自己控制Excel数据表的操作,又加入了检查校验和修复的功能,让程序员在数据表衔接部分也能进行检查和校验。