概述
UE4的對象系統可以說是整個引擎的核心模塊,其在引擎中的地位如下圖:
該對象系統具有很強的擴展性,新增的類只需要從UObject類繼承下來就可以融入到對象系統中。
對象系統具有如下幾個特性:
- 反射對象屬性和方法
- 對象的序列化
- 垃圾回收
- 創建和查找對象
- 通過配置文件設置對象的默認屬性
- 網絡支持(Replication和RPC)
C++語言本身不支持上述功能,為了實現上述功能,引擎定義了對象基類UObject, UObject類和其子孫類分別擁有一個UClass實例, UClass實例作為對象類的元數據(meta data),描述了類的反射信息和其它編輯器需要的信息。
Unreal Reflection System:
Each class that derives from UObject has a singleton UClass created for it that contains all of the meta data about the class instance. UObject and UClass together are at the root of everything that a gameplay object does during its lifetime. The best way to think of the difference between a UClass and a UObject is that the UClass describes what an instance of a UObject will look like, what properties are available for serialization, networking, etc.
整個對象系統,跟UE3比較起來變化不大。Blueprint對應UE3中的uc腳本系統和Kismet。 UE3通過在uc中定義一些uc class屬性,通過uc編譯器進行生成C++頭文件;UE4通過在C++的頭文件中的類定義中加入些宏(確切地說是空宏),讓UnrealHeaderTool對.h文件進行預處理,產生一些C++ .h,.cpp文件,這些代碼充當膠水層,將C++ Class加入Reflection功能。
注:UE3中的Kismet也是一個通過可視化連線達到編程目的,但是談不上一個語言,其連接結點由C++代碼實現;Blueprint集成了uc腳本和Kismet的功能,既能可視化編程又能夠后端生成uc虛擬機字節碼執行(也可以生成其它語言),所以Blueprint又叫Kismet2(這也許就是引擎Blueprint的接口有K2前綴的原因)。
對象的名字空間
與UE3類似,在對象系統中,每個對象有唯一的路徑名和類型(路徑名相同但類型不同是允許的)。這點應該是學習Java的包命名方式吧。
舉個例子:
上圖中FirstPerson_Run資源的全路徑名為:
AnimSequence'/Game/FirstPerson/Animations/FirstPerson_Run.FirstPerson_Run'。
- AnimSequence 是資源對象類名
- /Game/FirstPerson/Animations/ 是資源所在的路徑(游戲項目的Content目錄下的FirstPerson/Animations目錄)
- FirstPerson_Run.FirstPerson_Run 第一個FirstPerson_Run是包名(加載到內存后對應一個UPackage實例, 每個uasset文件對應為一個包,第二個FirstPerson_Run是動畫序列對象的名字,它的類型是AnimSequece。在虛幻中把第一個FirstPerson_Run對象稱為第二個FirstPerson_Run對象的Outer。
通過類型和路徑名就可以精確找到該對象。
注:在UE3中是對象名字空間是不帶有資源所在路徑這一因素的。
行程安排
代碼模塊:
- RunTime\UObjectCore 對象系統
- RunTime\Core 封裝平臺相關代碼和算法
后續對象系統系列文章將從如下幾個方面進行著手:
- 對象的類描述,主要通過UClass類來實現。
- 與UClass的相關概念
- UClass實例的創建
- 分析一個由UnrealHeaderTool生成的反射代碼
- 對象的創建流程和查找
- 對象的序列化, 文件格式,Linker
- 垃圾回收流程和機制
- Blueprint的原理 和 VM
a. Blueprint的可視化描述
b. 字節碼生成
c. VM的執行 - 模塊機制,如何實現hot-reload
- 對象的Replication(Network)
使用UE4開發應用必須要了解對象系統(特別是1-5點),在開發中會碰到有的同學創建的對象被莫名其妙地回收了,導致系統崩潰。究其原因就是沒有了解對象系統是如何利用UClass提供的信息來進行GC的,在定義C++類時是否需要給成員變量加UPROPERTY宏犯迷糊。