UE4中在C++内向黑板添加枚举数据并设置拾取器约束类型

前言

在C++中编写行为树时,需要向黑板中写入数据。对于普通数据,引擎封装的非常好,虚幻借助一组装饰器将常规类型做了封装。我们可以很轻松的向黑板中写入数据,但是除了一种,就是枚举。

枚举的特殊主要体现在进行数据装填时,你无法像其他数据类型一样确定枚举的类型。例如黑板中你添加的整型,布尔,向量,字符串,包括U类对象,他们都是有确定类型或类型关系的。而枚举无继承,并且多样性(蓝图枚举,C++枚举),这就为写入黑板数据增加了不少困难。

但是在虚幻引擎中,使用反射机制,却能够很好的解决这个问题。所以,你要知道,能够写入到黑板中的枚举类型,必须是被标记序列化的(C++中)!这也是使用前提条件。

PS:我发现在FBlackboardKeySelector中有函数AddNativeEnumFilter,但是并没有理解使用方法(我查了资料,在旧版本中可以直接使用设置约束枚举,但是4.21.2测试无效),如果你知道请留言告诉我,感谢~

添加枚举约束

行为树中可以被重写的有任务节点,装饰器,服务。三者都可能需要使用到在面板上拾取黑板中的数据,如果希望拾取黑板中的数据需要添加FBlackboardKeySelector类对象,类型为非指针型

UPROPERTY(EditAnywhere)
FBlackboardKeySelector KeyEnumSelector;

如果希望只能拾取黑板中的某些枚举数据,则可以使用以下代码(代码添加在构造函数中)

//添加C++中构建的枚举项,枚举标记序列化
KeyEnumSelector.AddEnumFilter(this, GET_MEMBER_NAME_CHECKED(UBTTaskNode_FindPatrolPos, KeyEnumSelector), FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnumA")));
//添加蓝图中构建的枚举
KeyEnumSelector.AddEnumFilter(this, GET_MEMBER_NAME_CHECKED(UBTTaskNode_FindPatrolPos, KeyEnumSelector), FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnumBP")));

添加后在面板上即可拾取黑板中枚举类型,并且类型是“EEnumA”和“EEnumBP”类型

关于序列化后枚举获取,也可以用于输出枚举项文本名称,例如在虚幻中打印枚举名称到控制台,代码如下

UEnum* pEnum = FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnumA"));

if (pEnum)
{
	//type为枚举变量值
	FText itemName = pEnum->GetDisplayNameTextByValue((int64)Type);
	UE_LOG(LogTemp, Log, TEXT("%s"), *itemName.ToString());
}

面板拾取结果

面板中显示信息
黑板中数据(注意C++中的枚举只能通过文本方式添加)
黑板中数据(蓝图可以直接拾取)

向黑板中写入数据

//通过selector向黑板中写入数据,注意1只是我随意填写的正常你需要填入枚举项值
//如果是蓝图枚举数据类型也无所谓,反正枚举是按照常整型处理的
OwnerComp.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Enum>(KeyEnumSelector.GetSelectedKeyID(), 1);
//注意上面代码中的函数SetValue是黑板组件成员函数,只要持有黑板组件指针就可以操作

写入数据中的1是我随便填写,你可以填入你的枚举变量,蓝图由于无法在C++中构建,所以只能填入整型(本来蓝图构建的枚举在C++中是无法直接使用的)

写入数据后均成功更新到黑板中

从黑板中读取数据

//读取黑板中的枚举数据,由于无法选定枚举类型只返回整型结果,需要自己根据变量类型选择强转
uint8 type = OwnerComp.GetBlackboardComponent()->GetValue<UBlackboardKeyType_Enum>(KeyEnumSelector.GetSelectedKeyID());

读取到的数据是整型,如果你知道枚举的特性,如何使用就不用我说了吧~

祝各位在虚幻里玩的愉快~

虚幻版本:V4.21.2

添加评论

您的电子邮箱地址不会被公开。