前言
在C++中编写行为树时,需要向黑板中写入数据。对于普通数据,引擎封装的非常好,虚幻借助一组装饰器将常规类型做了封装。我们可以很轻松的向黑板中写入数据,但是除了一种,就是枚举。
枚举的特殊主要体现在进行数据装填时,你无法像其他数据类型一样确定枚举的类型。例如黑板中你添加的整型,布尔,向量,字符串,包括U类对象,他们都是有确定类型或类型关系的。而枚举无继承,并且多样性(蓝图枚举,C++枚举),这就为写入黑板数据增加了不少困难。
但是在虚幻引擎中,使用反射机制,却能够很好的解决这个问题。所以,能够写入到黑板中的枚举类型,必须是被标记序列化的(C++中)!这也是使用前提条件。
我发现在FBlackboardKeySelector中有函数AddNativeEnumFilter,但是并没有理解使用方法(我查了资料,在旧版本中可以直接使用设置约束枚举,但是4.21.2测试无效),如果你知道请留言告诉我,感谢~
添加枚举约束
行为树中可以被重写的有任务节点,装饰器,服务。三者都可能需要使用到在面板上拾取黑板中的数据,如果希望拾取黑板中的数据需要添加FBlackboardKeySelector类对象,类型为非指针型。
关于FBlackboardKeySelector使用可以参考虚幻引擎黑板键拾取器(FBlackboardKeySelector)
1
2
|
UPROPERTY(EditAnywhere)
FBlackboardKeySelector KeyEnumSelector;
|
如果希望约束拾取的黑板中枚举类型,则可以使用以下代码(代码添加在构造函数中)
1
2
3
4
|
//添加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”类型
关于序列化后枚举获取,也可以用于输出枚举项文本名称,例如在虚幻中打印枚举名称到控制台,代码如下
1
2
3
4
5
6
7
8
|
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++中的添加的枚举只能通过文本方式添加)
黑板中数据(蓝图可以直接拾取)
C++中向黑板写入数据
1
2
3
4
|
//通过selector向黑板中写入数据,注意1只是我随意填写的正常你需要填入枚举项值
//如果是蓝图枚举数据类型也无所谓,反正枚举是按照常整型处理的
OwnerComp.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Enum>(KeyEnumSelector.GetSelectedKeyID(), 1);
//注意上面代码中的函数SetValue是黑板组件成员函数,只要持有黑板组件指针就可以操作
|
写入数据中的1是我随便填写,你可以填入你的枚举变量,蓝图由于无法在C++中构建,所以只能填入整型(本来蓝图构建的枚举在C++中是无法直接使用的)
写入数据后均成功更新到黑板中
C++从黑板中读取数据
1
2
|
//读取黑板中的枚举数据,由于无法选定枚举类型只返回整型结果,需要自己根据变量类型选择强转
uint8 type = OwnerComp.GetBlackboardComponent()->GetValue<UBlackboardKeyType_Enum>(KeyEnumSelector.GetSelectedKeyID());
|
读取到的数据是整型,如果你知道枚举的特性,如何使用就不用我说了吧~
祝各位在虚幻里玩的愉快~
虚幻版本:V4.21.2