UE4运用C++和框架开发坦克大战教程笔记(十六)(第49~50集)
49. 创建多个资源对象
补全调用链并测试生成多个同种类名资源对象
上节写好了 DDWealth 里的创建同种类名资源对象的方法,这集开头先来补充完整 DDWealth – DDModule – DDOO – 对象 这条调用链。
DDModule.h
public:
// 创建同资源种类名的对象实例,同种类名下的每个资源链接创建一个对象实例
void BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName ObjectName, FName FunName, TArray<FTransform> SpawnTransforms);
DDModule.cpp
void UDDModule::BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName ObjectName, FName FunName, TArray<FTransform> SpawnTransforms)
{
Wealth->BuildKindClassWealth(WealthType, WealthKind, ObjectName, FunName, SpawnTransforms);
}
对于 DDOO 来说,要根据生成对象的种类类型来区分调用方法。并且也不需要传 ObjectName,因为它自带有。
DDOO.h
protected:
// 创建同资源种类名的对象实例,同种类名下的每个资源链接创建一个对象实例
void BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName);
void BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName, FTransform SpawnTransform);
void BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName, TArray<FTransform> SpawnTransforms);
DDOO.cpp
// 区分点在于传入多少个 FTransform
// 对 Widget 类型
void IDDOO::BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName)
{
IModule->BuildKindClassWealth(WealthType, WealthKind, GetObjectName(), FunName, TArray<FTransform>{
FTransform::Identity });
}
// 对 Object 类型
void IDDOO::BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName, FTransform SpawnTransform)
{
IModule->BuildKindClassWealth(WealthType, WealthKind, GetObjectName(), FunName, TArray<FTransform>{
SpawnTransform });
}
// 对 Actor 类型
void IDDOO::BuildKindClassWealth(EWealthType WealthType, FName WealthKind, FName FunName, TArray<FTransform> SpawnTransforms)
{
IModule->BuildKindClassWealth(WealthType, WealthKind, GetObjectName(), FunName, SpawnTransforms);
}
接下来到 WealthCallObject 里进行验证。我们打算生成 3 个同种类名的对象到场景中,并且让它们一直旋转。
WealthCallObject.h
public:
// 回调方法
UFUNCTION()
void BuildActorKind(TArray<FName> BackNames, TArray<AActor*> BackActors);
public:
// 存储生成的 Actor
TArray<AActor*> KindActors;
WealthCallObject.cpp
void UWealthCallObject::DDLoading()
{
// 生成 3 个偏移的位置
TArray<FTransform> SpawnTransforms;
for (int i = 0; i < 3; ++i) {
SpawnTransforms.Push(FTransform(ViewTrans.GetLocation() + FVector(OffsetValue * i, 0.f, 0.f)));
}
// 测试完毕后注释掉这句
BuildKindClassWealth(EWealthType::Actor, "ViewActor", "BuildActorKind", SpawnTransforms);
}
void UWealthCallObject::DDTick(float DeltaSeconds)
{
for (int i = 0; i < KindActors.Num(); ++i)
KindActors[i]->AddActorWorldRotation(FRotator(1.f, 0.f, 0.f));
}
void UWealthCallObject::BuildActorKind(TArray<FName> BackNames, TArray<AActor*> BackActors)
{
for (int i = 0; i < BackNames.Num(); ++i)
DDH::Debug() << BackNames[i] << DDH::Endl();
KindActors = BackActors;
}
编译后,因为我们在 PlayerData 里已经配置好了 3 个 ViewActor 的数据,所以直接运行游戏,可以看到左上角输出了三个对象的名字,并且场景中它们 3 个在旋转。说明批量生成同种类名 Actor 对象的逻辑写好了。
实现创建多个同资源名的对象实例
前面实现了创建同种类名(WealthKind)的多个资源对象,现在我们来实现创建多个同资源名(WealthName)的资源对象。
DDWealth.h
// 加载批量同名 Class
struct ClassMultiLoadNode;
UCLASS()
class DATADRIVEN_API UDDWealth : public UObject, public IDDMM
{
GENERATED_BODY()
public:
// 创建多个同资源名的对象实例
void BuildMultiClassWealth(EWealthType WealthType, FName WealthName, int32 Amount, FName ObjectName, FName FunName, TArray<FTransform> SpawnTransforms);
protected:
// 处理创建多个对象的方法
void DealClassMultiLoadStack();
protected:
TArray<ClassMultiLoadNode*> ClassMultiLoadStack;
protected:
// 批量生成同名 Object 对象的回调函数
DDOBJFUNC_TWO(BackObjectMulti, FName, BackName, TArray<UObject*>, BackObjects);
// 批量生成同名 Actor 对象的回调函数
DDOBJFUNC_TWO(BackActorMulti, FName, BackName, TArray<AActor*>, BackActors);
// 批量生成同名 Widget 对象的回调函数
DDOBJFUNC_TWO(BackWidgetMulti, FName, BackName, TArray<UUserWidget*>, BackWidgets);
};
DDWealth.cpp
struct ClassMultiLoadNode
{
// 加载句柄
TSharedPtr<FStreamableHandle> WealthHandle;