寫在前面
游戲開發(fā)中唤反,不可避免的要和數(shù)據(jù)表打交道埂奈。而合格的程序員也要考慮怎樣完成游戲的數(shù)據(jù)驅(qū)動营曼,從而使自己得到解放帝牡,將更多的功能開放給策劃操作。作為游戲策劃也希望盡可能多的功能是可配置的个少,這樣方便我們快速修改并在游戲中驗(yàn)證對錯優(yōu)劣洪乍。
數(shù)據(jù)表的格式的選擇是見仁見智的事情。我這里簡單將自己的思考過程和實(shí)現(xiàn)方式記錄下來夜焦,權(quán)當(dāng)給大家做個參考吧壳澳!
這篇文章的視頻版在這里:
====
====
交流QQ群:872537977
項(xiàng)目地址github:
準(zhǔn)備工作
實(shí)際上KBEngine官方給我們提供了一個將Excel轉(zhuǎn)換為Python文件的工具。只要按照官方的格式書寫配置表茫经,就可以了巷波。
但是UE4要使用的數(shù)據(jù)表格式是csv或者json萎津。雖然KBEngine提供的工具可以生成json文件,但這種文件和UE4的因此我們需要考慮改寫現(xiàn)有的工具抹镊,使其可以同時生成前后端都可用的數(shù)據(jù)格式锉屈。
后端我們采用官方的python文件格式不修改。前端我們考慮怎樣將配置表改為csv格式垮耳,并導(dǎo)入游戲中成為UE4為我們提供的DataTable格式文件颈渊。
文件目錄
我們在項(xiàng)目根目錄下新建一個DataTables文件夾用于存放我們Excel數(shù)據(jù)表,然后將數(shù)據(jù)表通過工具生成csv和python文件终佛,并且分別存放在相應(yīng)的位置俊嗽。
然后我們翻看KBEngine自帶的導(dǎo)表工具,通過批處理文件中的代碼铃彰,我們知道工具的主體是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
就是我們要操作的字典單元。這里我們只需要對這個字典進(jìn)行操作就好了牙捉,將這個python字典轉(zhuǎn)換為我們想要的csv格式的文件就是今天的主要工作了竹揍。
通過百度,我們發(fā)現(xiàn)pandas
非常適合這項(xiàng)工作邪铲,關(guān)于它的用法這里不多說了鬼佣,就直接拿來用吧:
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()
# 補(bǔ)充csv相關(guān)代碼
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存為一個列表蓝纲。然后將這個列表轉(zhuǎn)換為csv格式即可阴孟。最后使用dp.to_csv將其存到磁盤中的指定位置,后面的header和index默認(rèn)都是True可以省略税迷,這里還是捎帶提一句永丝,分別是代表頭一行和索引列的含義,最后生成的文件如下圖所示:
我們來實(shí)驗(yàn)一下這個文件能否導(dǎo)入UE4中使用箭养,在content位置右鍵慕嚷,選擇這個導(dǎo)入即可:
這時候發(fā)現(xiàn)它彈出一個選項(xiàng):
這里讓我們選擇數(shù)據(jù)表的行類型,什么是行類型毕泌?實(shí)際上UE4中的DataTable都要和一個Struct對應(yīng)喝检,所以這里我們根據(jù)數(shù)據(jù)的類型手動添加一個對應(yīng)的結(jié)構(gòu)體藍(lán)圖,如下圖所示:
有了這個結(jié)構(gòu)體撼泛,我們再導(dǎo)入這個文件試一下挠说,結(jié)果果然成功生成了一個DataTable文件,命名和csv文件的命名一致愿题,打開這個文件我們看一下如下圖所示:
這樣我們想要實(shí)現(xiàn)的效果就完成了损俭!是不是很簡單蛙奖。
但是這個工具并不完美,有很多可以優(yōu)化的地方杆兵,不過今天時候不早了就先不寫了雁仲,占個坑之后再把它填上。
可優(yōu)化的點(diǎn)
生成文件位置
既然是自動生成配置文件琐脏,索性就直接將生成好的文件放在客戶端和服務(wù)器相應(yīng)的位置只需要我們手動比對差異后提交即可攒砖。這才是真正意義上的自動化呀,這個需要優(yōu)化
自動生成結(jié)構(gòu)體文件
上面的操作中有一個步驟是手動編輯一個結(jié)構(gòu)體藍(lán)圖骆膝。有個問題就是當(dāng)表的結(jié)構(gòu)發(fā)生變化的時候我們還要手動修改結(jié)構(gòu)體藍(lán)圖祭衩,并且新建表格時候也需要新建結(jié)構(gòu)體藍(lán)圖。自動化不夠徹底阅签。
這里我還沒有實(shí)際操作掐暮,但是一種可行的方案就是代碼的自動生成,我們可以通過配置像生成python文件一樣生成C++的結(jié)構(gòu)體文件政钟。理論上是可行的路克。這個我們之后有機(jī)會可以試一下。
將CSV反向保存為Excel(或python)文件
既然我們可以將python字典轉(zhuǎn)換為csv文件养交,那么理論上也可以通過編輯UE4中的DataTable導(dǎo)出csv之后反向?qū)霝閜ython字典精算。不過這樣依然不徹底。最好的方式是能夠?qū)xcel原始數(shù)據(jù)文件進(jìn)行修改碎连』矣穑或者說盡量不進(jìn)行反向操作。DataTable文件是只讀的鱼辙。這里還沒想好廉嚼,先寫著備忘吧。
下期預(yù)告
做好了這個前期準(zhǔn)備工作倒戏,就可以心無旁騖的搞定我們的角色選擇(新建角色)界面了怠噪。這個是我們下一步的內(nèi)容。
除此之外杜跷,我還想寫一個小工具——掉落模擬器傍念,在工作中配置了掉落數(shù)據(jù)表之后,需要驗(yàn)證一下掉落概率葛闷。所以我想實(shí)現(xiàn)一個讀取配置表數(shù)據(jù)之后憋槐,通過輸入掉落ID和次數(shù)自動將“可能產(chǎn)生的掉落道具名稱、ID和掉落次數(shù)淑趾,實(shí)際概率”這些數(shù)據(jù)打印出來秦陋,甚至保存到文件中的一個小工具。等我寫完了也會分享給大家治笨,算是個小禮物吧驳概。:)
我是老李赤嚼,一個做游戲的,除了游戲不會別的顺又。
困得不行更卒,先睡了。晚安各位稚照。