寫在前面的一段話:
之前準備用LuaServer寫一個簡單moba手遊,後來覺得,LuaServer畢竟是前公司內部的產品,不是絕對開源的,也因着別的一些原因,決定放棄更新LuaServer相關的。
但個人學習不能停是不是,哈哈哈…今兒起,準備搗鼓搗鼓KBEngine。KBEngine之前也沒有接觸過,Unity也好久沒碰過了,於是乎,就準備把這兩者結合下,實現從入門到“放棄”的一個小目標吧。
這系列文章,會伴隨自己業餘時間,便實現代碼便總結記錄,當做一份學習筆記。
這裏準備利用KBEngine作爲服務端引擎,將Unity官網的坦克大戰demo進行改造,目標是實現一個聯機版坦克大戰,同步方式採用狀態同步來完成。
從上層功能開發入手,然後深入到源碼層,以此完成一次自我學習的過程~同時,代碼會在github上同步更新。
階段目標
- 環境搭建
- 客戶端能和KBEngine完成通信
- Server端完成基本的從匹配到進入戰場的功能,客戶端做出響應
環境搭建
KBEngine官網:KBEngine官方網站
KBEngine源碼:github源碼
Unity版本:Unity 2019.1.0f2 (64-bit)
坦克大戰demo:在Unity的Asset Store裏面搜索關鍵字"Tanks"免費獲取
服務端基礎配置:WampServer
KBEngine默認是需要mysql數據庫支持的,爲了便於開發,減少前期投入的時間,利用WampServer傻瓜式一鍵式搭建一個簡易的mysql運行環境。
關於KBEngine環境的具體搭建,參考官網,官網的環境搭建文檔還是很詳細的,文檔傳送門在此:點我!傳送門
流程設計
簡單瞭解了下,KBEngine的cell部分主要承擔的是space內相關的數據操作,比如移動、戰鬥等等,base上承擔的則是一些基礎性的東西。(這是剛接觸時,給我的感覺,可能說的不準備,等待後續深入學習再具體看)。基於這個認識,我們從登陸、匹配到進入戰場的第一階段目標,基本上和cell是無關的,全部在base上實現得了。
先奉上一份上述操作的設計流程時序圖:
相關說明
- Account是kbe引擎層在客戶端登錄時默認創建的第一個entity實體,配置第一個實體的文件在assets\res\server\kbengine.xml裏面的accountEntityScriptType字段
- Account的任務就是驗證登錄相關性,所以在驗證完成後,我會創建出一個PlayerAvatar的對象,並把Account的proxy轉移給PlayerAvatar,此後與客戶端交互的對象就從Account轉移到PlayerAvatar身上了。同時,真正進入相應space空間的是PlayerAvatar這個entity而非Account,Account在此時是可以考慮destroy了的。(對於proxy的解釋,放在後續文章裏,這裏簡單理解爲通過他就可以和客戶端通信就好~)。
- SpaceMgr是一個全局的Space管理器,所有的Space(大廳、戰場等)全部由這個管理器來維護管理,SpaceMgr本身也是一個Entity。
相關代碼
Account.py
def becomePlayerAvatar(self):
"""
從Account成爲Avatar
:return:
"""
avatar = KBEngine.createEntityLocally('PlayerAvatar', {})
if avatar:
DEBUG_MSG("Account[%i].becomePlayerAvatar\n" % self.id)
self.activeAvatar = avatar
self.giveClientTo(self.activeAvatar)
PlayerAvatar.py
def onClientEnabled(self):
INFO_MSG("PlayerAvatar::onClientEnabled, ready to enter space")
spaceMgr = KBEngine.globalData['SpaceMgr']
spaceMgr and spaceMgr.enterSpace(self, SpaceType.SPACE_TYPE_HALL)
SpaceRoom.py
def avatarReqMatch(self, avatarID):
INFO_MSG("[SpaceRoom], %i, %i, avatar:%s reqMatch." % (self.id, self.uType, avatarID))
self._wait_to_match_avatar_set.add(avatarID)
matchNum = len(self._wait_to_match_avatar_set)
if matchNum >= MatchArgs.BATTLE_ROOM_MATCH_PLAYER_NUM:
INFO_MSG("[SpaceRoom], %i, %i, ready to enter battle room" % (self.id, self.uType))
for _ava_id in self._wait_to_match_avatar_set:
_avatar = self._avatar_dict.get(_ava_id, None)
_avatar and _avatar.client.onEnterBattleRoom()
self._wait_to_match_avatar_set = set()
return
for ava_id in self._wait_to_match_avatar_set:
_avatar = self._avatar_dict.get(ava_id, None)
if not _avatar:
continue
_avatar.client.onMatch(matchNum)
上述源碼地址
至此,一個特別特別版的初步目標達成了,可以從客戶端發起登錄、匹配、完成匹配的流程。這個版本里面,硬編碼寫死了2人匹配,匹配完成後直接跳到熟悉的坦克大戰場景。。
畫面很突兀,也沒潤色,有畫面感的版本會在第二篇文章裏面給出,這篇文章的個人小目標就是實現一次基本的通信流程。
guthub源碼地址: 聯機版坦克大戰github地址