UE4行为树中在黑板内使用枚举类型(C++)

前言

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

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

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

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

添加枚举约束

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

关于FBlackboardKeySelector使用可以参考虚幻引擎黑板键拾取器(FBlackboardKeySelector)

1UPROPERTY(EditAnywhere)
2FBlackboardKeySelector KeyEnumSelector;

如果希望约束拾取的黑板中枚举类型,则可以使用以下代码(代码添加在构造函数中)

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

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

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

1UEnum* pEnum = FindObject<UEnum>(ANY_PACKAGE, TEXT("EEnumA"));
2 
3if (pEnum)
4{
5    //type为枚举变量值
6    FText itemName = pEnum->GetDisplayNameTextByValue((int64)Type);
7    UE_LOG(LogTemp, Log, TEXT("%s"), *itemName.ToString());
8}

面板拾取结果

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

C++中向黑板写入数据

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

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

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

C++从黑板中读取数据

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

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

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

虚幻版本:V4.21.2

文章评论