01 - 类与对象

本文主要说明了UE5中类与对象的基本概念:

  • UClass()宏;
  • UObject类常用知识点;

UClass()

UClass()宏为我们创建的UObject提供了“引用”,它保留一个称为 类默认对象(Class Default Object)的对象,简称CDO。CDO本质上是一个默认模板对象,由类构造函数生成,之后变为只读不再修改。

可以获取指定对象的只读CDO:

UClass* MyUClass = AMyActor::StaticClass();
UObject* MyUObject = MyUClass->GetDefaultObject();
AMyActor* CDO = Cast<AMyActor>(MyUObject);

UClass()宏还能包含定义类的一些属性和函数,前提是这些类的属性和函数要被UPROPERTY()UFUNCTION()标记,进入反射系统中。

TSubclassOf

TSubclassOf<>是提供UClass类型安全性的模板类,与UClass*相比,该模板类更安全,可以让用户选择指定类的派生类。

UObject

UObject类是UE5中所有对象的基类,实际上它有诸如UObjectBaseUtilityUObjectBase的父类,但一般不直接使用。

UObject类提供了如下功能:

  • 垃圾回收
  • 引用更新
  • 反射
  • 序列化
  • 默认属性变化自动更新
  • 自动属性初始化
  • 自动编辑器整合
  • 运行时类型信息可用
  • 网络复制

创建UObject

所有的C++UObject都会在游戏启动时通过默认构造函数进行初始化,常用到的构造函数有如下两个:

UObject();
UObject(cosnt FObjectInitializer& ObjectInitializer);

如果想在引擎运行时动态创建UObject实例,应通过NewObject<>()CreateDefaultSubobject<>()来创建UObject,有关这两个函数的使用方法在这里可以参考:

更新UObject

对于子类AActor,它在注册时会自动调用它们的Tick()函数。然而UObject没有此功能,如果要让UObject实现Tick(),需要让其继承FTickableGameObject,并实现Tick()

销毁UObject

当一个UObject不被引用后,垃圾回收系统GC将自动进行对象销毁。GC在运行时,将0被引用的对象从内存中移除。

可通过调用对象的MarkPendingKill()(或MarkAsGarbage())方法将所有指向该对象的指针设为NULL,将其标记为PendingKill,并交给GC进行销毁。

有关垃圾回收的具体内容和相关设置说明详见这里

UObject与UHT

UHT负责预处理UObject相关的宏,以便实现它的相关功能。需要注意的是,如果我们使用自创的宏去包含UCLASS()等内容,UHT会扫描不到进而无法生成反射文件,最终报错。解决该问题的方法就是去引擎源码中创建UHT和自创宏的关联,即实现UHT处理该自创宏的逻辑。

参考资料

  • UE5 虚幻引擎UEC++从基础到进阶_哔哩哔哩_bilibili

  • Objects in Unreal Engine