《InsideUE4》GamePlay架構(四)Pawn

我像是一顆棋

進退任由你決定

我不是你眼中唯一將領

卻是不起眼的小兵

引言

歡迎來到GamePlay架構章節的下半部分!

在上一篇的內容里,我們談到了UE的3D遊戲世界是由Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine來逐漸層層構建而成的。那麼從這下半章節開始,我們就將要開始逐一分析,UE是如何在每一個對象層次上表達遊戲邏輯的。和分析對象節點樹一樣,我們也將採用自底向上的方法,從最原始簡單的對象開始。

首先需要明確的是,本部分接下來要講述的UE的GamePlay邏輯框架部分,只是討論UE的設計思想和理念,並不是表示其在所有其他遊戲引擎中是最優最完美的方案,同時當然也不是開發人員務必遵守的金科玉律,你依然可以也應該根據自己實際情況靈活變通。UE經過了很多權衡設計和歷史進化,最後選擇了該設計方案,一方面和對象層級相輔相成,另一方面也提供了足夠的自由度可以供你騰挪。

實現一個遊戲業務功能的方式有多種,你應該盡量妥善的權衡你當前的現實情況,考慮生產效率、維護性、功能實現、易理解、性能等等多種因素,然後選擇你認為最恰當的方式。如果你當前在製作一個快速原型Demo,你大可以簡單粗暴,我也不贊成時刻謹遵教條主義一定要分層拆分如何如何;而如果是面對一個正式的比較大型項目,隨著規模的擴大,我們就得利用清晰的概念來幫助我們減輕心智負擔。UE作為一個老牌的經歷了十幾年風風雨雨的遊戲引擎,也當然有它的一套GamePlay哲學。我們選擇了UE,接受了在UE的工作流之下工作,如果我們能比較好的理解它的概念和思想,就能更加的「順」著它的思路,得心應手海闊任魚躍。而如果我們「逆」著這個框架來搞自己的一套,一是不免有無法充分利用UE的嫌疑,二也是以UE的龐大和根深錯節難免讓你碰一頭灰費力不討好。

Note1:雖然本部分會涉及到遊戲的業務邏輯編寫部分,但並不打算詳細討論AI(BehaviorTree,Navigation等)。AI也是一個很大的話題,值得專門開個大章節討論,我們現在不應該委屈她。

Note2:本部分也不會細討論輸入事件的處理,遊戲邏輯確實一大部分是由輸入事件驅動起來的,不過我們此時只是簡單聊一下概念,後續會有章節再細討論輸入事件的路由流程。

Note3:聯機遊戲的遊戲邏輯自然也是非常重要的,但為了簡化本章節的概念,所以網路聯機的邏輯同步等也都不會涉及。留待後續網路章節再好好的闡述。

Component

Actor可以說是由Component組成的,所以Component其實是我們對象樹里最底層的員工了。在UE里,Component表達的是「功能」的概念。比如說你要實現一個可以響應的WASD移動的功能,或者是VR里抓取的功能,甚至是嵌套另一個Actor的功能,這些都是一個個組件。正確理解「功能」和「遊戲業務邏輯」的區分是理解Component的關鍵要點。

所以我們在這一個層級上要編寫的邏輯,是實現一個個「與特定遊戲無關」的功能。理想情況下,等你的一個遊戲完成,你那些已經實現完成的Components是可以無痛遷移到下一個遊戲中用的。換言之,一旦你發現你在Component中含有遊戲的業務邏輯代碼,這就是所謂的「Bad Smell」了,要警惕遊戲架構是否恰當,是否沒有很清晰的概念劃分。

Actor

如果說UE是一個大國家的話,那Actor無疑就是人口最大的民族了。StaticMeshActor,CameraActor……我們天天口裡嚷嚷的也都是它。和Unity的Prefab對應的,在UE里我們用的最多的也是BlueprintActor了,我們也常常自定義我們的Actor子類來組裝其他Component和Actor,然後再編寫一些協作邏輯代碼,就似乎完成了一個驍勇善戰的特種兵,接下來就可以撒豆成兵般的往Level中扔了。

用的越廣泛越多,往往錯的也越多。似乎是受到了一種樸素的子承父業的精神感染,也或許是我們的面向對象編程都學得太好的緣故,我們都非常傾向於直接在Actor里堆砌邏輯。右鍵一個BlueprintActor,剛添加完Component,就立馬擼起袖子來,Event、Function和Variable一個個羅列開來,噼里啪啦無不快活!但是且慢,這是最好的方式了嗎?讓我們一路帶著這個問題,試著從UE角度去推演一下,重走一下Actor進化之路。在本章節旅程的終點,我保證,我們可以比較清楚的回答這個問題。

其實所有的遊戲引擎在構建完節點樹之後,都會面臨這麼一個問題,我的遊戲邏輯寫在哪裡?

有的原始的如Cocos2dx懶得想那麼多,乾脆就直接碼在Node裡面得了,所以你翻看Cocos2dx的源碼你就會經常發現它的邏輯和表現往往是交雜在一起的,簡單直接暴力美學,面向對象繼承玩得溜。而面向組合陣營的領軍Unity則乾脆就把Component思想再應用極致一點,我的邏輯為什麼不能也是一個組件?所以Unity里的ScriptComponent也是這種組合思想的體現,模型統一架構優雅,MonoBehavior立大功了!但是在一個Component(ScriptComponent)里去操作管理其他的Components,本身卻其實並不是那麼優雅,因為有些Component之上的協調管理的事務,從層次上來說,應該放在更高的一個概念上實現。UE在思考這個問題時,卻是感覺有些理想主義,頗有些C++的理念,力求不為你不需要的東西付代價,寧願有時候折衷,也想保住最優性能。UE的架構中也大量應用了各種繼承,有些繼承鏈也能拉得很長,同時一方面也吸納了組合的優點,我們也能見到UE的源碼中類的成員變數也是組合了好多其他對象。所以接下來的該介紹的就是UE綜合應用這兩種思想的設計產物。面向對象派生下來的Pawn和Character,支持組合的Controller們。

Pawn

那麼第二個至關重要的的問題是,哪些Actor需要附加邏輯?

在遊戲中,我們之所以會覺得一個角色生動,是因為它會響應我們的交互,並給出恰當的反應。而我們所謂的遊戲業務邏輯,實際上編寫的就是該如何對玩家的輸入提供反饋。同樣,一個Actor想要變得「生動」,就得有響應外部輸入的能力,否則就只是自動運轉麻木的機器人。但是在一個比較大型的3D遊戲中,Actor有千千萬萬,然後並不是所有的Actor都需要和玩家互動,得寵的能直接面聖和玩家互動的Actor也是比較少的。我們經常都只是操作我們的「角色」,讓「角色」和場景里的其他物體互動。比如FPS遊戲里我們操作的主角或者是FlappyBird里的那隻小鳥。所以從這一點上來看,UE中Actor就立馬又可以劃分出一個類別了,這些Actor們可謂是玩家們的寵兒,它們是玩家們的親衛兵,對,它的名字就是Pawn!

同其他AInfo一樣,UE也是從Actor中再派生出了APawn,並定義了3塊基本的模板方法介面:

1. 可被Controller控制

2. PhysicsCollision表示

3. MovementInput的基本響應介面

為了更好理解這個概念,讓我們看一下用搜索引擎搜一下Pawn得到的圖:

沒錯,Pawn的英文翻譯過來可以是兵卒,所以如果把UE遊戲看作是一場棋盤上的遊戲的話,那這些Pawn就可以看作是在UE的3D世界中玩家可以操縱的棋子,而其他的Actor則可以構成棋盤等。如果是人機對戰的話,對方玩家是機器AI,同樣需要控制Pawn棋子。所以Pawn就是那些可以被玩家(你或AI)控制的Actor!再考察到UE是做FPS遊戲起家的,所以你可以想像這個Pawn就相當於戰場里最基本的士兵的表示。一個士兵在戰場中首先需要表達自身的存在(PhysicsCollision),可以移動(MovementInput),然後可以響應輸入和處理邏輯(Controller),有了這三個基本要素,運用你的想像力,你就可以大概構想出一個被玩家控制的「兵卒」的模樣和概念了。

要非常清楚一點的是,Actor是我們用來表示3D遊戲中對象的,所以Pawn繼承於Actor,概念的重點是在於更清楚的去表示,而不是重點在於Pawn被當作邏輯的載體,就像棋子本身只能簡單的表達出出個棋子,但是該如何走還是得再靠外部的Controller機制。你也可以想像成提線木偶,那個木偶就是Pawn,而提線的是Controller。Pawn表達的最關鍵點是可被玩家操縱的能力。因為UE從FPS進化過來的關係,所以附帶的物理表示和移動也一併加了進去,應該也是為了方便的緣故。就像我知道Damage這種業務邏輯部分按照純粹性來說是不應該出現在引擎的代碼里的,但是Actor里就是這麼加上了,用的時候也確實能得到便利。遊戲引擎是個工程,而不是科學研究,有時候確實模塊劃分也不是那麼純粹。

思考:為何Actor也能接受Input事件?

我上述的對Pawn的描述可能會讓你覺得,似乎Pawn既然就是用來被玩家控制的,那麼理所當然的我們應該在Pawn上同時實現對輸入的接受。但我們會發現實際上EnableInput介面卻是在Actor上的,同時InputComponent也是在Actor裡面的,意味著實際上你也可以在Actor上綁定處理輸入事件。官方的輸入事件處理流程圖也是表明了這一點:

(暫時不用細研究這個圖,我們以後會再次見到的。)

我們在此暫不細討論輸入流程為何如此設計,只談談該如何理解這一事實。首先應該不難理解輸入的處理功能可以實現化出InputComponent,而「輸入」的種類也有很多(按鍵、搖桿、觸摸和陀螺儀等等),我們也不能確定和分類哪些Actor的子類該接受哪些種類的輸入事件;同時又因為Actor也是由Component組件化組裝而成的,UE不可能為了輸入的處理就改變Component的組織方式,所以還不如泛泛的在Actor的基類里提供InputComponent的集成,這樣反而保證了靈活性。

理解這個問題的要點在於正確區分「輸入響應」和「邏輯控制」。比如說WASD移動,Actor擁有最基本的輸入響應,它可以響應WASD的按鍵事件。但是按鍵了之後呢?該如何移動?Pawn就定義了一個基本的MovementInput套路,相當於把WASD的輸入響應再往前包裝處理了一步。而「邏輯控制」指的是更高層上的比如尋路或自動巡邏等行為。

作為GamePlay中至關重要的一個邏輯概念,讓我再羅嗦強調一遍應該不為過吧。Pawn實現的是「可被控制」的概念。因為「被控制了」之後經常要被移動(UE對FPS是真愛啊),所以Pawn就索性把移動的介面也定義了一下(當然,為了靈活性,內部轉交給MovementComponent再處理),既然能移動了,但也不能隨便在地圖裡亂走吧,所以碰撞(物理表示)看來也是需要的啊,好吧,那就加上,齊活了。

DefaultPawn,SpectatorPawn,Character

讓我一口氣介紹下面這三位:

DefaultPawn

因為我們每次想自己搞Pawn都得從Pawn派生過來,然後再一個個添加組件。UE知道我們大家都很懶,所以提供了一個默認的Pawn:DefaultPawn,默認帶了一個DefaultPawnMovementComponent、spherical CollisionComponent和StaticMeshComponent。也是上述Pawn闡述過的三件套,只不過都是默認套餐。

SpectatorPawn

UE的FPS做的太好了,就會有一些觀眾想要觀戰。觀戰的玩家們雖然也在當前地圖裡,但是我們並不需要真正的去表示它們,只要給他們一些攝像機「漫遊」的能力。所以派生於DefaultPawn的SpectatorPawn提供了一個基本的USpectatorPawnMovement(不帶重力漫遊),並關閉了StaticMesh的顯示,碰撞也設置到了「Spectator」通道。

Character

因為我們是人,所以在遊戲中,代入的角色大部分也都是人。大部分遊戲中都會有用到人形的角色,既然如此,UE就為我們直接提供了一個人形的Pawn來讓我們操縱。

像人一樣行走的CharacterMovementComponent, 盡量貼合的CapsuleComponent,再加上骨骼上蒙皮的網格。同樣的三件套,不一樣的配方。

有些人一開始的時候會困惑應該選擇Pawn還是Character,其實從繼承體系中就可以了解到Character只不過是Pawn的加強特化版本。一般來說,如果你控制的角色是人形的帶骨骼的,那就選擇Character吧。而如果是VR中的一雙手(假設只有一雙手),因為移動模式和顯示都算不太上人形,頂多只能算是個漂浮的「幽靈」,所以還是用Pawn方便些。後期如果你想加上人形模型和IK了,那麼再把Mesh替換成SkeletalMesh也就行了。Pawn因為是基礎款,所以提供了最大的靈活性。

總結

本篇主要探討了從Actor到Pawn的分化過程,請讀者們也好好自己體會一下這一過程中UE的設計和思量。一個遊戲引擎對3D遊戲世界的抽象是建立在很多概念之上的,UE的邏輯和實現也都是基於對這些概念的實現和封裝。而如果讀者你並不清晰理解這些概念,那麼就很難正確的應用和組織遊戲的邏輯各個部分。本系列教程一如開篇所說,並不會教你應用的各種技巧,而把重點放在討論UE背後的各種概念,這些才是讓我們的頭腦保持清晰的關鍵之處。

因為在下筆力有限,很遺憾,我們心心念念的Controller只好留待下篇了。我在談Pawn的時候,因為Pawn和Controller是那麼緊密的關聯著,所以也不得不事先一再的劇透提到Controller。但Controller作為GamePlay邏輯的最最重要的一個載體,可探討的點也非常的多,所以留待下篇吧。

上篇:《InsideUE4》GamePlay架構(三)WorldContext,GameInstance,Engine

下篇:《InsideUE4》GamePlay架構(五)Controller

引用

  1. Pawn
  2. Character

UE4.14

---------------------------------------------------------------------------------------------------------------------------

知乎專欄:InsideUE4

UE4深入學習QQ群:456247757(非新手入門群,請先學習完官方文檔和視頻教程)

微信公眾號:aboutue,關於UE的一切新聞資訊、技巧問答、文章發布,歡迎關注。

個人原創,未經授權,謝絕轉載!


推薦閱讀:

遊必有方 Vol.10 NYU Practice 系列活動現場彙報(上)
技術宅救世界:英國遊戲行業的啟蒙往事
寫在《卡片怪獸》成功之前

TAG:游戏引擎 | 虚幻引擎 | 游戏开发 |