在上一篇的內容里,我們談到了UE的3D游戲世界是由Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine來逐漸層層構建而成的。那么從這下半章節(jié)開始,我們就將要開始逐一分析,UE是如何在每一個對象層次上表達游戲邏輯的。和分析對象節(jié)點樹一樣,我們也將采用自底向上的方法,從最原始簡單的對象開始。
首先需要明確的是,本部分接下來要講述的UE的GamePlay邏輯框架部分,只是討論UE的設計思想和理念,并不是表示其在所有其他游戲引擎中是最優(yōu)最完美的方案,同時當然也不是開發(fā)人員務必遵守的金科玉律,你依然可以也應該根據(jù)自己實際情況靈活變通。UE經(jīng)過了很多權衡設計和歷史進化,最后選擇了該設計方案,一方面和對象層級相輔相成,另一方面也提供了足夠的自由度可以供你騰挪。
實現(xiàn)一個游戲業(yè)務功能的方式有多種,你應該盡量妥善的權衡你當前的現(xiàn)實情況,考慮生產(chǎn)效率、維護性、功能實現(xiàn)、易理解、性能等等多種因素,然后選擇你認為最恰當?shù)姆绞健H绻惝斍霸谥谱饕粋€快速原型Demo,你大可以簡單粗暴,我也不贊成時刻謹遵教條主義一定要分層拆分如何如何;而如果是面對一個正式的比較大型項目,隨著規(guī)模的擴大,我們就得利用清晰的概念來幫助我們減輕心智負擔。UE作為一個老牌的經(jīng)歷了十幾年風風雨雨的游戲引擎,也當然有它的一套GamePlay哲學。我們選擇了UE,接受了在UE的工作流之下工作,如果我們能比較好的理解它的概念和思想,就能更加的“順”著它的思路,得心應手海闊任魚躍。而如果我們“逆”著這個框架來搞自己的一套,一是不免有無法充分利用UE的嫌疑,二也是以UE的龐大和根深錯節(jié)難免讓你碰一頭灰費力不討好。
Note1:雖然本部分會涉及到游戲的業(yè)務邏輯編寫部分,但并不打算詳細討論AI(BehaviorTree,Navigation等)。AI也是一個很大的話題,值得專門開個大章節(jié)討論,我們現(xiàn)在不應該委屈她。
Note2:本部分也不會細討論輸入事件的處理,游戲邏輯確實一大部分是由輸入事件驅動起來的,不過我們此時只是簡單聊一下概念,后續(xù)會有章節(jié)再細討論輸入事件的路由流程。
Note3:聯(lián)機游戲的游戲邏輯自然也是非常重要的,但為了簡化本章節(jié)的概念,所以網(wǎng)絡聯(lián)機的邏輯同步等也都不會涉及。留待后續(xù)網(wǎng)絡章節(jié)再好好的闡述。
Component
Actor可以說是由Component組成的,所以Component其實是我們對象樹里最底層的員工了。在UE里,Component表達的是“功能”的概念。比如說你要實現(xiàn)一個可以響應的WASD移動的功能,或者是VR里抓取的功能,甚至是嵌套另一個Actor的功能,這些都是一個個組件。正確理解“功能”和“游戲業(yè)務邏輯”的區(qū)分是理解Component的關鍵要點。
所以我們在這一個層級上要編寫的邏輯,是實現(xiàn)一個個“與特定游戲無關”的功能。理想情況下,等你的一個游戲完成,你那些已經(jīng)實現(xiàn)完成的Components是可以無痛遷移到下一個游戲中用的。換言之,一旦你發(fā)現(xiàn)你在Component中含有游戲的業(yè)務邏輯代碼,這就是所謂的“Bad Smell”了,要警惕游戲架構是否恰當,是否沒有很清晰的概念劃分。
Actor
如果說UE是一個大國家的話,那Actor無疑就是人口最大的民族了。StaticMeshActor,CameraActor……我們天天口里嚷嚷的也都是它。和Unity的Prefab對應的,在UE里我們用的最多的也是BlueprintActor了,我們也常常自定義我們的Actor子類來組裝其他Component和Actor,然后再編寫一些協(xié)作邏輯代碼,就似乎完成了一個驍勇善戰(zhàn)的特種兵,接下來就可以撒豆成兵般的往Level中扔了。
用的越廣泛越多,往往錯的也越多。似乎是受到了一種樸素的子承父業(yè)的精神感染,也或許是我們的面向對象編程都學得太好的緣故,我們都非常傾向于直接在Actor里堆砌邏輯。右