对象创建方法示例集
创建Actor示例
//创建一个护甲道具
AProp* armor = GetWorld()->SpawnActor<AProp>(pos, rotator);
创建Component示例
UCapsuleComponent* CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("CapsuleComponent"));
创建加载资源对象示例
UStaticMesh* chairMesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, TEXT("/Game/Assets/Props/StaticMeshe/ChairMesh"))); UStaticMeshComponent* StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
StaticMesh ->SetStaticMesh(chairMesh);
创建UObject示例
UItemBase* ItemCopy = NewObject<UItemBase>(StaticClass());
在上面的创建加载资源对象和UObject示例中都出现了StaticCalss()方法,下面就说说相关的内容。
关于StaticClass、GetClass和ClassDefaultObject
UClass和反射
什么是反射?
反射的作用是在不知道这个类的情况下获取到它的信息 。
UC++底层实现了一套反射机制。
先看C#怎么用反射:
string s = "Hello,guys!”;
Type t = s.GetType();
Type里面就包含了string这个类的各种信息。
UClass就是C#里的Type。
UClass和C#里的Type的作用不完全相同,可以这么理解。
GetClass()
GetClass() 类似C#的GetType。
类静态方法获取StatiClass
UClass* PropUClass = APropArmor::StaticClass();
如何知道一个UClass和另一个UClass是不是继承关系?
UClass存储了它要描述的类的父类的StaticClass。 举例说明:假如有个MyActor类的UClass,想知道MyActor是不是UObject的子类,可以这么做:
- 调用UObject::StaticClass()
- 拿到MyActor的UClass存储的MyActor的父类的StaticClass也就是Actor的StaticClass
- 比较Actor的StaticClass和UObject的StaticClass是不是相等
- 发现不相等,这次我拿Actor的StaticClass(因为它也是一个UClass)里存的Actor父类的StaticClass也就是UObject的StaticClass,然后比较,发现相等,返回true
- 如果我发现不相等,我就一直比,比到最后没有父类,返回false
上面这段逻辑就是UClass的IsChildOf的实现原理。调用IsChildOf的时候传入泛型:
这是具体实现。UStruct是UClass父类。
GetSuperStruct()就是返回它存储的父类的StaticClass。
顺带再讲一下IsA这个函数,功能和IsChildOf一样,不同的是IsChildOf给UClass用的,IsA是给UObject对象实例用的,比如想知道一个MyActor实例是不是UObject的子类:
//myActor是MyAcor*类型
bool result = myActor->IsA<UObject>();
ClassDefaultObject
ClassDefaultObject(简称CDO),类默认对象。
通过CDO我可以拿到一个UObject初始化时的值。
虽然CDO有个Default默认,但是用默认去描述它的功能不是很准确。回到我们创建的类MyActor,给它添加一个外部可以修改变量testIntValue,默认值1:
对于两个蓝图分别修改,一个20,另一个10:
然后在BeginPlay写下测试代码:
//先修改值再获取ClassDefaultObject
testIntValue = -1;
auto defaultInt = GetClass()->GetDefaultObject<AMyActor>()->testIntValue;
UE_LOG(LogTemp, Warning, TEXT("DefaultObject int: %d"), defaultInt);
最后打印的结果是一个20,一个10。
如果想拿到代码里给它设的默认值1要用StaticClass:
auto staticDefaultInt = AMyActor::StaticClass()->GetDefaultObject<AMyActor>()->testIntValue;
//打印1
UE_LOG(LogTemp, Warning, TEXT("StaticDefaultObject int: %d"), staticDefaultInt);
总结
- UClass。存储类信息,用于反射。把它当成C#的Type来理解。
- GetClass()。获得一个UObject实例的UClass,是UObject成员函数。
- GetStaticClass()。不需要有实例就能获得UClass。是静态的,每次调用返回相同结果。
- ClassDefaultObject。类默认对象,可以获得UObject初始化时的值。注意GetClass()->GetDefaultObject()和T::StaticClass()->GetDefaultObject()不一样。
参考链接:Unreal Engine 4 C++ 创建对象的几种方法_uec++创建对象-CSDN博客
参考链接:【UE·底层篇】一文搞懂StaticClass、GetClass和ClassDefaultObject - 知乎