引言

上篇我們講到了UE在World之上,繼續(xù)抽象出了Player的概念,包含了本地的ULocalPlayer和網(wǎng)絡(luò)的UNetConnection,并以此創(chuàng)建出了World中的PlayerController,從而實(shí)現(xiàn)了不同的玩家模式策略。一路向上,依照設(shè)計里一個最樸素的原理:自己是無法創(chuàng)建管理自身的,所以Player也需要一個創(chuàng)建管理和存儲的地方。另一方面,上文提到Player固然可以負(fù)責(zé)一些跟玩家相關(guān)的業(yè)務(wù)邏輯,但是對于World之上協(xié)調(diào)管理的邏輯卻也仍然無處安放。
如果是有一定的游戲開發(fā)實(shí)戰(zhàn)經(jīng)驗(yàn)的朋友也一定能體會到,在自己開發(fā)的游戲中,往往除了我們上文提到的Player類,常常會創(chuàng)建一個Game類,比如BattleGame、WarGame或HappyGame等等。Game之前的名詞往往都是游戲的開發(fā)代號。這倒不是因?yàn)槲覀內(nèi)绱藷嶂詣?chuàng)建各種Manager類,而是確實(shí)需要一個大管家來干一些協(xié)調(diào)的活。一般的游戲引擎都只會暴露給你它自己引擎的管理類,如Director,Engine或Application之類的,但是卻不會主動在Game類的創(chuàng)建管理上為你提供方便。游戲引擎的出現(xiàn),最開始其實(shí)只是因?yàn)橐恍┤税l(fā)現(xiàn)游戲做著做著,有一大部分功能是可以復(fù)用的,于是就把它抽離了出來方便做下一款游戲。在那個時候,人們對游戲還是處于開荒探索的階段,游戲引擎只是一大堆功能的復(fù)合體,就像叮當(dāng)貓的口袋一樣,互相比誰掏出的工具最強(qiáng)大。然而即使到了現(xiàn)代,絕大部分的引擎的思想?yún)s還停留在上個世紀(jì),仍然執(zhí)著于羅列Feature列表,卻忘了真正的游戲開發(fā)人員天天面對的游戲業(yè)務(wù)邏輯編寫,沒有思考在那方面如何也下一番功夫去幫助開發(fā)者。人們對比UE和其他游戲引擎時,也會常常說出的一句話是:“別忘了Epic自己也是做游戲的”(虛幻競技場,戰(zhàn)爭機(jī)器,無盡之劍……)。從這一點(diǎn)也可以看出,UE很大的得益于Epic實(shí)戰(zhàn)游戲開發(fā)的反哺,這一方面Unity就有點(diǎn)吃虧了,沒有自己親自下手干臟活累活,就不懂得急人民群眾之所急。所以如果一個游戲引擎能把GamePlay也做好了,那就不止是口袋了,而是知你懂你的叮當(dāng)貓本身。

GameInstance

簡單的事情就不用多講了,UE提供的方案是一以貫之的,為我們提供了一個GameInstance類。為了受益于UObject的反射創(chuàng)建能力,直接繼承于UObject,這樣就可以依據(jù)一個Class直接動態(tài)創(chuàng)建出來具體的GameInstance子類。

我并不想羅列所有的接口,UGameInstance里的接口大概有4類:

  1. 引擎的初始化加載,Init和ShutDown等(在引擎流程章節(jié)會詳細(xì)敘述)
  2. Player的創(chuàng)建,如CreateLocalPlayer,GetLocalPlayers之類的。
  3. GameMode的重載修改,這是從4.14新增加進(jìn)來改進(jìn),本來你只能為特定的某個Map配置好GameModeClass,但是現(xiàn)在GameInstance允許你重載它的PreloadContentForURL、CreateGameModeForURL和OverrideGameModeClass方法來hook改變這一流程。
  4. OnlineSession的管理,這部分邏輯跟網(wǎng)絡(luò)的機(jī)