Garbage collection:垃圾收集
Reference updating:引用自动更新
Reflection:反射
Serialization:序列化
Automatic updating of default property changes:自动检测默认变量的更改
Automatic property initialization:自动变量初始化
Automatic editor integration:和虚幻引擎编辑器的自动交互
Type information available at runtime:运行时类型识别
Network replication:网络复制
主要:
+ [[C++API/反射系统|反射系统]]
+ 内存管理、垃圾回收
+ 序列化模型、SaveGame
+ Class Default Object CDO 类默认对象
+ 编辑器可见
+ 元数据 UClass SubClassOf<>
+ 网络同步
UObject 虚幻对象
Object Actor ActorComponent UStruct
从UObject派生的子类,都会创建一个UClass
UClass会包含该类所有的元数据(代码中定义的类型、成员以及代码中引用的类型和成员)
UObject 和 UClass 处于对象生命周期的最根部。
UClass在描述UObject创建的实例的样子,提供了可序列化的联网等功能
[[反射系统]]:
+ UCLASS:生成反射数据,前提是类必须是UObject
+ USTRUCT:生成反射数据
+ UPROPERTY:变量的网络复制,序列化,蓝图访问等,GC调用,获取UObject的引用次数
+ UFUNCTION:蓝图调用函数,RP等
+ GENERATED_BODY():在类的最开始的位置
最下方的头文件:`#include "类名.generated.h"`
# UObject 和 垃圾回收
垃回程ll序中维护了一个**根集**,
根集存储着一堆对象,GC不会回收的对象都存储在根集中,
在根集中,某个对象到一个对象存在引用路径,就不会对其进行垃圾回收
如果某个对象不存在到根集的路径,则认为无法访问,GC会在下次执行时将其回收(删除)
引擎的GC是按照固定时间间隔来运行程序
UPROPERTY 和 容器(TArray,TMap,TSet)中存储的UObject\* 指针都被当做是垃圾回收引用
纯C++类:
FGCObject
重写纯虚函数:`AddReferencedObjects(FReferenceCollector& Collector)`
# UObject 类默认对象
UClass TsubClassOf CDO
UClass:保存着反射数据 或者 保存着一个类的各种信息
TsubClass UClass的模板类
CDO 类默认对象,Class Default Object 每个继承于UObject的类都有CDO 记录了初始的信息
获取UClass的函数:GetClass() 成员函数 StaticClass() 静态函数
然后通过UClass->GetDefaultObject()
在纯C++中工作时:
1. 使用对象的`GetClass()`成员函数和该对象类的`StaticClass()`静态成员函数,两者都会返回相同的`UClass`指针。这是因为该对象是直接由其C++类实例化的,没有任何派生的蓝图类存在。
但当您使用C++类作为蓝图的基类时,情况就会变得有些复杂:
2. 当您在编辑器中从C++基类创建蓝图,您实际上是在创建该基类的子类。这个新的子类是蓝图生成的,并且包含了蓝图中定义的任何额外的逻辑和数据。因此,这个蓝图实际上是您的C++类的一个派生类。
3. 当您实例化这个蓝图,`GetClass()`会返回这个特定蓝图的`UClass`,因为您实际上是在实例化该蓝图类,而不是原始的C++基类。
4. 然而,当您在这个蓝图对象上调用`StaticClass()`时,由于这是一个静态方法,它实际上是基类上的方法,所以它返回的是C++基类的`UClass`。
这就是为什么在创建了基于C++基类的蓝图后,这两个函数的返回值会不同:`GetClass()`返回的是实际蓝图的`UClass`,而`StaticClass()`返回的是C++基类的`UClass`。
这种设计允许Unreal Engine在C++和蓝图之间进行无缝的交互,同时保留了C++的类型信息和蓝图的扩展性。
> UClass 不仅需要记录类型信息,还需要承担序列化工作,数据也需要记录
# UObject 查找(迭代器)
```cpp
void AMyActorForLearn::LearnFunc_FindObject()
{
#if 0
//查找世界的UObject
for(TObjectIterator<UObject> It;It;++It)
{ UObject* Current = *It; UKismetSystemLibrary::PrintString(GetWorld(),Current->GetName()); }#endif
//查找世界中的AActor
for(TActorIterator<AActor> It(GetWorld(),GetClass());It;++It)
{ auto Current = *It;
UKismetSystemLibrary::PrintString(GetWorld(),Current->GetName());
} //根据类获取Actor
auto Actor = UGameplayStatics::GetActorOfClass(GetWorld(),GetClass());
UKismetSystemLibrary::PrintString(GetWorld(),Actor->GetName());
//根据标签获取Actor
//UGameplayStatics::GetAllActorsWithTag(); //UGameplayStatics::GetAllActorsOfClassWithTag();}
```