概述
UE4的對(duì)象系統(tǒng)可以說(shuō)是整個(gè)引擎的核心模塊,其在引擎中的地位如下圖:

該對(duì)象系統(tǒng)具有很強(qiáng)的擴(kuò)展性,新增的類只需要從UObject類繼承下來(lái)就可以融入到對(duì)象系統(tǒng)中。
對(duì)象系統(tǒng)具有如下幾個(gè)特性:
- 反射對(duì)象屬性和方法
- 對(duì)象的序列化
- 垃圾回收
- 創(chuàng)建和查找對(duì)象
- 通過(guò)配置文件設(shè)置對(duì)象的默認(rèn)屬性
- 網(wǎng)絡(luò)支持(Replication和RPC)
C++語(yǔ)言本身不支持上述功能,為了實(shí)現(xiàn)上述功能,引擎定義了對(duì)象基類UObject, UObject類和其子孫類分別擁有一個(gè)UClass實(shí)例, UClass實(shí)例作為對(duì)象類的元數(shù)據(jù)(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.
整個(gè)對(duì)象系統(tǒng),跟UE3比較起來(lái)變化不大。Blueprint對(duì)應(yīng)UE3中的uc腳本系統(tǒng)和Kismet。 UE3通過(guò)在uc中定義一些uc class屬性,通過(guò)uc編譯器進(jìn)行生成C++頭文件;UE4通過(guò)在C++的頭文件中的類定義中加入些宏(確切地說(shuō)是空宏),讓UnrealHeaderTool對(duì).h文件進(jìn)行預(yù)處理,產(chǎn)生一些C++ .h,.cpp文件,這些代碼充當(dāng)膠水層,將C++ Class加入Reflection功能。
注:UE3中的Kismet也是一個(gè)通過(guò)可視化連線達(dá)到編程目的,但是談不上一個(gè)語(yǔ)言,其連接結(jié)點(diǎn)由C++代碼實(shí)現(xiàn);Blueprint集成了uc腳本和Kismet的功能,既能可視化編程又能夠后端生成uc虛擬機(jī)字節(jié)碼執(zhí)行(也可以生成其它語(yǔ)言),所以Blueprint又叫Kismet2(這也許就是引擎Blueprint的接口有K2前綴的原因)。
對(duì)象的名字空間
與UE3類似,在對(duì)象系統(tǒng)中,每個(gè)對(duì)象有唯一的路徑名和類型(路徑名相同但類型不同是允許的)。這點(diǎn)應(yīng)該是學(xué)習(xí)Java的包命名方式吧。
舉個(gè)例子:

上圖中FirstPerson_Run資源的全路徑名為:
AnimSequence'/Game/FirstPerson/Animations/FirstPerson_Run.FirstPerson_Run'。
- AnimSequence 是資源對(duì)象類名
- /Game/FirstPerson/Animations/ 是資源所在的路徑(游戲項(xiàng)目的Content目錄下的FirstPerson/Animations目錄)
- FirstPerson_Run.FirstPerson_Run 第一個(gè)FirstPerson_Run是包名(加載到內(nèi)存后對(duì)應(yīng)一個(gè)UPackage實(shí)例, 每個(gè)uasset文件對(duì)應(yīng)為一個(gè)包,第二個(gè)FirstPerson_Run是動(dòng)畫序列對(duì)象的名字,它的類型是AnimSequece。在虛幻中把第一個(gè)FirstPerson_Run對(duì)象稱為第二個(gè)FirstPerson_Run對(duì)象的Outer。
通過(guò)類型和路徑名就可以精確找到該對(duì)象。
注:在UE3中是對(duì)象名字空間是不帶有資源所在路徑這一因素的。
行程安排
代碼模塊:
- RunTime\UObjectCore 對(duì)象系統(tǒng)
- RunTime\Core 封裝平臺(tái)相關(guān)代碼和算法
后續(xù)對(duì)象系統(tǒng)系列文章將從如下幾個(gè)方面進(jìn)行著手:
- 對(duì)象的類描述,主要通過(guò)UClass類來(lái)實(shí)現(xiàn)。
- 與UClass的相關(guān)概念
- UClass實(shí)例的創(chuàng)建
- 分析一個(gè)由UnrealHeaderTool生成的反射代碼
- 對(duì)象的創(chuàng)建流程和查找
- 對(duì)象的序列化, 文件格式,Linker
- 垃圾回收流程和機(jī)制
- Blueprint的原理 和 VM
a. Blueprint的可視化描述
b. 字節(jié)碼生成
c. VM的執(zhí)行 - 模塊機(jī)制,如何實(shí)現(xiàn)hot-reload
- 對(duì)象的Replication(Network)
使用UE4開發(fā)應(yīng)用必須要了解對(duì)象系統(tǒng)(特別是1-5點(diǎn)),在開發(fā)中會(huì)碰到有的同學(xué)創(chuàng)建的對(duì)象被莫名其妙地回收了,導(dǎo)致系統(tǒng)崩潰。究其原因就是沒有了解對(duì)象系統(tǒng)是如何利用UClass提供的信息來(lái)進(jìn)行GC的,在定義C++類時(shí)是否需要給成員變量加UPROPERTY宏犯迷糊。