写在前面
游戏开发中,不可避免的要和数据表打交道。而合格的程序员也要考虑怎样完成游戏的数据驱动,从而使自己得到解放,将更多的功能开放给策划操作。作为游戏策划也希望尽可能多的功能是可配置的,这样方便我们快速修改并在游戏中验证对错优劣。
数据表的格式的选择是见仁见智的事情。我这里简单将自己的思考过程和实现方式记录下来,权当给大家做个参考吧!
这篇文章的视频版在这里:
====
https://b23.tv/av68309438
====
交流QQ群:872537977
项目地址github:
Liweimin0512/uRPGgithub.com
准备工作
实际上KBEngine官方给我们提供了一个将Excel转换为Python文件的工具。只要按照官方的格式书写配置表,就可以了。
但是UE4要使用的数据表格式是csv或者json。虽然KBEngine提供的工具可以生成json文件,但这种文件和UE4的因此我们需要考虑改写现有的工具,使其可以同时生成前后端都可用的数据格式。
后端我们采用官方的python文件格式不修改。前端我们考虑怎样将配置表改为csv格式,并导入游戏中成为UE4为我们提供的DataTable格式文件。
文件目录
我们在项目根目录下新建一个DataTables文件夹用于存放我们Excel数据表,然后将数据表通过工具生成csv和python文件,并且分别存放在相应的位置。
然后我们翻看KBEngine自带的导表工具,通过批处理文件中的代码,我们知道工具的主体是xlsx2py.py
文件,注意看以下这一段:
def writeBody(self):
#for index in self.curProIndex:
# xlsxError.info_input(EXPORT_INFO_ING, (self.xbook.getSheetNameByIndex(index).encode(FILE_CODE), ))
self.xlsxWrite(EXPORT_DATA_HEAD)
if "globalDefs" in g_fdatas:
self.xlsxWrite(g_fdatas["globalDefs"])
for dataName, datas in g_dctDatas.items():
stream = dataName + "="
#stream += xlsxtool.dict_to_text(datas) + "\n"
stream += "%s\n" % (datas)
self.xlsxWrite(stream)
jsonhandle = codecs.open(self.fileHandler.stream.name + "." + dataName + ".json", "w+",'utf-8')
s = json.dumps(datas)
jsonhandle.write("{%s}" % (s[1:-1]))
jsonhandle.close()
其中json的路径是下面这行代码:
jsonhandle = codecs.open(self.fileHandler.stream.name + "." + dataName + ".json", "w+",'utf-8')
通过查看生成后json文件的命名:
基本猜测出datas
就是我们要操作的字典单元。这里我们只需要对这个字典进行操作就好了,将这个python字典转换为我们想要的csv格式的文件就是今天的主要工作了。
通过百度,我们发现pandas
非常适合这项工作,关于它的用法这里不多说了,就直接拿来用吧:
import pandas as pd
'''
...
'''
def writeBody(self):
#for index in self.curProIndex:
# xlsxError.info_input(EXPORT_INFO_ING, (self.xbook.getSheetNameByIndex(index).encode(FILE_CODE), ))
self.xlsxWrite(EXPORT_DATA_HEAD)
if "globalDefs" in g_fdatas:
self.xlsxWrite(g_fdatas["globalDefs"])
for dataName, datas in g_dctDatas.items():
stream = dataName + "="
#stream += xlsxtool.dict_to_text(datas) + "\n"
stream += "%s\n" % (datas)
self.xlsxWrite(stream)
jsonhandle = codecs.open(self.fileHandler.stream.name + "." + dataName + ".json", "w+",'utf-8')
s = json.dumps(datas)
jsonhandle.write("{%s}" % (s[1:-1]))
jsonhandle.close()
# 补充csv相关代码
arr = list(datas.values())
dp = pd.DataFrame(arr)
dp.to_csv(self.fileHandler.stream.name + "." + dataName + ".csv",header=True,index=True)
代码非常简单,以entities.py文件为例:
datas就是“=”后面的部分,也就是一个字典。我们只需将这个字典中所有的value存为一个列表。然后将这个列表转换为csv格式即可。最后使用dp.to_csv将其存到磁盘中的指定位置,后面的header和index默认都是True可以省略,这里还是捎带提一句,分别是代表头一行和索引列的含义,最后生成的文件如下图所示:
我们来实验一下这个文件能否导入UE4中使用,在content位置右键,选择这个导入即可:
这时候发现它弹出一个选项:
这里让我们选择数据表的行类型,什么是行类型?实际上UE4中的DataTable都要和一个Struct对应,所以这里我们根据数据的类型手动添加一个对应的结构体蓝图,如下图所示:
有了这个结构体,我们再导入这个文件试一下,结果果然成功生成了一个DataTable文件,命名和csv文件的命名一致,打开这个文件我们看一下如下图所示:
这样我们想要实现的效果就完成了!是不是很简单。
但是这个工具并不完美,有很多可以优化的地方,不过今天时候不早了就先不写了,占个坑之后再把它填上。
可优化的点
生成文件位置
既然是自动生成配置文件,索性就直接将生成好的文件放在客户端和服务器相应的位置只需要我们手动比对差异后提交即可。这才是真正意义上的自动化呀,这个需要优化
自动生成结构体文件
上面的操作中有一个步骤是手动编辑一个结构体蓝图。有个问题就是当表的结构发生变化的时候我们还要手动修改结构体蓝图,并且新建表格时候也需要新建结构体蓝图。自动化不够彻底。
这里我还没有实际操作,但是一种可行的方案就是代码的自动生成,我们可以通过配置像生成python文件一样生成C++的结构体文件。理论上是可行的。这个我们之后有机会可以试一下。
将CSV反向保存为Excel(或python)文件
既然我们可以将python字典转换为csv文件,那么理论上也可以通过编辑UE4中的DataTable导出csv之后反向导入为python字典。不过这样依然不彻底。最好的方式是能够对Excel原始数据文件进行修改。或者说尽量不进行反向操作。DataTable文件是只读的。这里还没想好,先写着备忘吧。
下期预告
做好了这个前期准备工作,就可以心无旁骛的搞定我们的角色选择(新建角色)界面了。这个是我们下一步的内容。
除此之外,我还想写一个小工具——掉落模拟器,在工作中配置了掉落数据表之后,需要验证一下掉落概率。所以我想实现一个读取配置表数据之后,通过输入掉落ID和次数自动将“可能产生的掉落道具名称、ID和掉落次数,实际概率”这些数据打印出来,甚至保存到文件中的一个小工具。等我写完了也会分享给大家,算是个小礼物吧。:)
我是老李,一个做游戏的,除了游戏不会别的。
困得不行,先睡了。晚安各位。