引擎版本:Unreal Engine 4.22
UObject
UE4的最基礎類型是UObject,它提供了如下功能:
- GC機制(垃圾回收機制)
- 引用自動更新
- 運行時類型識別
- 反射機制
- 序列化
- 自動檢測默認變量的變更
- 屬性自動初始化
- UE4編輯器的自動整合
- 網絡復制
- ...
這樣當我們編寫需要使用以上功能的類時,繼承一下UObject即可。
后面要講的Actor和Component便是這樣做的。
更多功能或細節,可參考源文件Engine\Source\Runtime\CoreUObject\Public\UObject\Object.h
Actor種類
每個游戲引擎都會有一個非常重要的游戲對象類型,在cocos2d-x里是Node(節點),在Unity3D里是GameObject(游戲對象),而在UE4里,這個重要的角色則是Actor(演員)。
可能在UE4引擎設計者的眼里,游戲世界是一個舞台,把各個Actor放置在舞台上面,便能展現出一出好戲。
在UE編輯器的World Outliner窗口可以看到當前場景的所有Actor實例:
AActor
AActor類是可以放到游戲場景中的游戲對象的基本類型,另外它更強大的能力是可以掛載組件(Component)。
組件提供功能,想讓一個實體Actor擁有更多的功能就可以通過掛載不同的組件實現。
可以看到AActor繼承於UObject,然后再派生出各式各樣的Actor類(例如APawn)。這是因為舞台需要放置各式各樣的演員,而在UE4的世界觀里,演員不僅包含游戲世界里的角色、NPC、載具,還可以是一間房子、一把武器、一個掉落的蘋果,甚至一個抽象的游戲規則、看不見的玩家控制器...
你如果想放置任何有實質作用的東西到游戲場景中,應該繼承AActor類。
APawn(可操控單位)
簡單來說,APawn類是一個代表可被控制的游戲對象(玩家角色、怪物、NPC、載具等),它繼承於AActor。
對於開發者,每次創建Pawn都得從Pawn類繼承,然后寫各種各樣的實現/添加各種各樣的組件。
於是UE4提供了幾個派生類作為模板,以便快速編寫自己的Pawn。
-
ADefaultPawn (默認的可操控單位)
DefaultPawn繼承於APawn,是一個默認的Pawn模板。它默認帶了一個DefaultPawnMovementComponent、SphericalCollisionComponent和StaticMeshComponent。
-
ASpectatorPawn(觀察者)
SpectatorPawn繼承於APawn,是適用於觀戰的Pawn模板,擁有攝像機“漫游”的能力。它實際就是提供了一個基本的USpectatorPawnMovement(不帶重力漫游),並關閉了StaticMesh的顯示,碰撞也設置到了“Spectator”通道。
-
ACharacter(角色)
Character繼承於APawn,是一個包含了行走,跑步,跳躍以及更多動作的Pawn模板。它含有像人一樣行走的CharacterMovementComponent,盡量貼合的CapsuleComponent,再加上骨骼上蒙皮的網格。
AController(控制器)
AController繼承於AActor,Controller通過接受玩家的設備(鍵盤、鼠標等)輸入或者被AI輸入來控制Pawn。實際上一個Pawn可以被多個Controller操控(例如載具可由一個玩家駕駛,另一個玩家操控車頂機槍),也可以切換Controller(例如,完成一段劇本演出時,玩家不能控制主角,而交由劇本腳本控制。)
-
APlayerController(玩家控制器)
APlayerController繼承於AController,負責接受玩家設備輸入從而控制Pawn,它提供了Camera(控制玩家視角)、設備輸入處理、關聯UPlayer、顯示HUD等功能、切換Level...
-
AAIController(AI控制器)
AAIController繼承於AController,負責提供AI從而控制Pawn,它提供了導航網格尋路、AI行為樹、Task系統...
AGameMode(游戲模式)
AGameMode繼承於AActor,這是一個很重要的類。因為一個GameMode定義了游戲的規則(例如如何得分或者其他方面的系統邏輯內容),我們經常需要繼承於它編寫自己游戲的全局規則/全局游戲邏輯。
由於游戲邏輯規則往往是單例的,我們可以通過UGameplayStatics::GetGameMode這個靜態函數來獲取GameMode的實例:
AMyGameMode* MyGameMode;
//得到自己定義的AMyGameMode實例
MyGameMode = Cast<AMyGameMode>(UGameplayStatics::GetGameMode(this));
此外GameMode默認是不打開每幀調用Tick事件的,這里我就被坑了下。
AHUD(HUD)
AHUD繼承於AActor,它是平面顯示界面,就是平時我們玩3D游戲提供給玩家的2D菜單界面。AHUD類提供了渲染文字、貼圖、矩形和材質的渲染,創建后也可以通過藍圖來編輯界面。
...
Component種類
隨意點擊一個Actor,可以查看該Actor的所有Component(組件):
UActorComponent(基本組件)
UActorComponent繼承於UObject,是最基本的組件類型。不過需要注意的是,它沒有Transform,也沒有提供嵌套包含其他Actor組件的功能。
這是因為在UE看來,Actor並不只是3D世界中的表示,一些不在世界中展示的“不可見對象”也可以是Actor,比如AInfo等,所以這些Actor的組件也就沒有自帶Transform了。
USceneComponent(場景組件)
繼承於UActorComponent,它封裝了Transform來表示其位置。所以需要位置表示的Actor就可以向Actor中添加SceneComponent作為其RootComponent(例如APawn就自動創建了SceneComponent)。
與此同時,得益於Transform(可以計算相對位置),SceneComponent可以允許嵌套包含其他Actor組件(例如一個人體組件包含身體組件,一個身體組件又可以包含手組件)。
實際中大部分的Actor是有Transform的,所以我們會經常設置獲取它的坐標。常理來說,我們的需要先獲取下SceneComponent,然后才能操作其Transform等相應接口。但是這樣太過繁瑣,因此UE為我們直接提供了基於Actor的接口,如(Get/Set)ActorLocation,但其實這些接口內部也是轉發到RootComponent的。
同理,Actor能接收處理Input事件的能力,其實也是轉發到Actor內部的UInputComponent* InputComponent;
UChildActorComponent(子演員組件)
繼承於USceneComponent,提供了Component之下再疊加Actor的能力,擔負着Actor之間互相組合的膠水。這貨在藍圖里靜態存在的時候其實並不真正的創建Actor,而是在之后Component實例化的時候才真正創建。
UStaticMeshComponent(靜態網格組件)
繼承於USceneComponent,是一個靜態網格組件,也就是提供一個靜態網格物體的渲染效果/物理碰撞等。
...
總結
實際上,UE4的Actor-Component系統就與Unity3D的GameObject-Component系統很相似。
一個游戲場景里擺放若干個演員(Actor),每個演員雖然空無一物(沒穿衣服),但是可以通過給它添加不同的服飾、台詞等(Component)從而展現出很多不同的性質,從而呈現出一款精彩的游戲舞劇。
而Actor的各種派生類實際上只是Acotr加上提前准備好這些特定的服飾台詞,簡單來說就是提供一種特殊演員的模板。
簡要的UObject-Actor-Component UML類圖:
參考
博主最近在通過UE4搗弄關於地形生成的DEMO,順便學習UE4,因此接下來還會有幾篇UE4筆記和地形生成研究的博客,敬請期待:)
至於筆記博客的標題,算是致敬笨木頭前輩的《cocos2d-x游戲開發之旅》吧。
系列其他文章:Aery的UE4 C++開發之旅系列文章