UE4 EQS C++自定义节点编写
目录
- 决策对象
- Generator
- Context
- Test
基础应用就不说了,直接看官方文档。
这篇主要讲怎么在C++层定义Generator、Test和Context。
决策对象
EQS的作用是做出最优决策,目前支持的决策对象包括:
- Actor
- Point
- Direction
Generator
按照上面所说,生成器可以生成可选的集合。
对于一个自定义C++ Generator来说,最起码需要实现两个函数:
- 构造函数
- 标明集合的类型(Actor, Point, Direction…)
GenerateItems()
往集合里添加元素QueryInstance.AddItemData<UEnvQueryItemType_Actor>(Element);
添加点元素QueryInstance.AddItemData<UEnvQueryItemType_Point>(Element);
添加Actor元素
下面以一个例子说明,这个例子会生成一个敌人的集合。
UEnvQueryGenerator_Enemy::UEnvQueryGenerator_Teammate(const FObjectInitializer& ObjectInitializer /*= FObjectInitializer::Get()*/)
{ItemType = UEnvQueryItemType_Actor::StaticClass();
}void UEnvQueryGenerator_Enemy::GenerateItems(FEnvQueryInstance& QueryInstance) const
{TWeakObjectPtr<UObject> OwnerPtr = QueryInstance.Owner;UObject* Owner = OwnerPtr.Get();MyCharactor* MyChar = Cast<MyCharactor>(Owner);if (MyChar != nullptr){TArray<ACharactor*> EnemyArray = MyChar->GetEnemys();for(const ACharactor* Enemy : EnemyArray){QueryInstance.AddItemData<UEnvQueryItemType_Actor>(Enemy);}}
}
筛选特定点的集合,可以参考UE4自带的源码EnvQueryGenerator_SimpleGrid
,原理上差不多,只是AddItemData的时候添加的是一个点FNavLocation
。
Context
Context的本质是返回一个参数,这个参数可以在Test中使用。
自定义C++ Context类只需要实现ProvideContext()
函数。在这个函数中,调用对应的UEnvQueryItemType::SetContextHelper()
方法来设置数据。
举个例子,我们需要拿到场上的一杯饮料作为参数,那么新建一个UEnvQueryContext_Drink
:
void UEnvQueryContext_Drink::ProvideContext(FEnvQueryInstance& QueryInstance, FEnvQueryContextData& ContextData) const
{AActor* QueryOwner = Cast<AActor>(QueryInstance.Owner.Get());UMyWorld* World = QueryOwner->GetWorld();ADrink* Drink = World->FindFirstDrink();if(Drink != nullptr){UEnvQueryItemType_Actor::SetContextHelper(ContextData, Drink);}
}
读者可以参考UE4源码UEnvQueryContext_Querier
,返回的是查询者本身。
Test
Test的目的有两个:Filter过滤不符合条件的,或者Score计算分值。
最简单的可以参考EnvQueryTest_GameplayTag
。
主要需要实现构造函数,以及函数RunTest()
。
在构造函数中,需要标明本Test的性能开销EEnvTestCost
,以及标明输入参数的合法类型UEnvQueryItemType
。
这里可以直接贴出EnvQueryTest_GameplayTag
的关键代码,供各位参考。
UEnvQueryTest_GameplayTags::UEnvQueryTest_GameplayTags(const FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
{Cost = EEnvTestCost::Low;SetWorkOnFloatValues(false);bUpdatedToUseQuery = false;ValidItemType = UEnvQueryItemType_ActorBase::StaticClass();
}void UEnvQueryTest_GameplayTags::RunTest(FEnvQueryInstance& QueryInstance) const
{UObject* QueryOwner = QueryInstance.Owner.Get();if (QueryOwner == nullptr){return;}BoolValue.BindData(QueryOwner, QueryInstance.QueryID);bool bWantsValid = BoolValue.GetValue();// loop through all itemsfor (FEnvQueryInstance::ItemIterator It(this, QueryInstance); It; ++It){// 使用`GetItemActor`获取集合的元素AActor* ItemActor = GetItemActor(QueryInstance, It.GetIndex());IGameplayTagAssetInterface* GameplayTagAssetInterface = Cast<IGameplayTagAssetInterface>(ItemActor);// 判断是否有某个tag,如果有,那么SetScore为trueif (GameplayTagAssetInterface != NULL){bool bSatisfiesTest = SatisfiesTest(GameplayTagAssetInterface);// bWantsValid is the basically the opposite of bInverseCondition in BTDecorator. Possibly we should// rename to make these more consistent.It.SetScore(TestPurpose, FilterType, bSatisfiesTest, bWantsValid);}else // If no GameplayTagAssetInterface is found, this test doesn't apply at all, so just skip the item.{ // Currently It.ForceItemState(EEnvItemStatus::Passed);}}
}
UE4 EQS C++自定义节点编写相关推荐
- 用mel编写自定义节点的属性编辑器界面
用mel编写自定义节点的属性编辑器界面比较麻烦,而且网上例子又少,下面给出一个范例,说明基本的格式 // 初始化节点时调用 global proc initControl(string $attrNa ...
- ue4当中材质自定义uv和多套uv
首先是多套uv 多套uv可以通过fbx方式导入到ue4中(obj只能一套) 在texcoord中index里面切换,从0开始为第一套uv ue4当中还支持自定义uv的 这个功能是用来优化效率的,特别带 ...
- 【UE4】实现自定义框选
要在UE4中实现自定义框选功能,首先我们来分析一下顶顶一框选插件需要些什么模块? 绘制模块 显示模块 计算模块 嗯,大概分这么三个模块,好,现在我们一个个模块来分析实现.首先分析实现一下显示模块. 提 ...
- Nginx自定义模块编写:根据post参数路由到不同服务器
Nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,Nginx默认的配置规则就捉襟见肘了,但是没关系,Nginx提供了强大的自 ...
- mfc 制作不同的文档模板mdi不同的子窗体_制作ACK集群自定义节点镜像的正确姿势...
随着云原生时代的到来,用户应用.业务上云的需求也越来越多,不同的业务场景对容器平台的需求也不尽相同,其中一个非常重要的需求就是使用自定义镜像创建ACK集群. ACK支持用户使用自定义镜像创建Kuber ...
- nginx自定义模块编写-实时统计模块--转载
原文:http://www.vimer.cn/2012/05/nginx%E8%87%AA%E5%AE%9A%E4%B9%89%E6%A8%A1%E5%9D%97%E7%BC%96%E5%86%99- ...
- 高级指引——自定义节点
title: 自定义节点 order: 1 G6 提供了一系列内置节点,包括 circle.rect.diamond.triangle.star.image.modelRect.若内置节点无法满足需求 ...
- nginx 加路由时报错_Nginx自定义模块编写:根据post参数路由到不同服务器
Nginx可以轻松实现根据不同的url 或者 get参数来转发到不同的服务器,然而当我们需要根据http包体来进行请求路由时,Nginx默认的配置规则就捉襟见肘了,但是没关系,Nginx提供了强大的自 ...
- 使用自定义DelegatingHandler编写更整洁的Typed HttpClient
使用自定义DelegatingHandler编写更整洁的Typed HttpClient 简介 我写了很多HttpClient[1],包括类型化的客户端.自从我发现Refit[2]以来,我只使用了那 ...
最新文章
- 条件队列大法好:wait和notify的基本语义
- java发送html模板
- dsa java_将Java转换为python DSA签名
- 牛客网 【每日一题】5月9日 过河
- java9-1.类,抽象类,接口的综合小练习
- html分类页面,CSS网页设计 把HTML标记分类
- Python之日志处理(logging模块)详解
- java 发送cookie_java – 如何在response.sendRedirect()之后发送cookie?
- 通过jQuery获取窗口的高度
- 通过ajax获取经纬度,通过百度地图获取经纬度
- 美国计算机访学,计算机应用专业4天喜获美国加州大学洛杉矶分校访问学者职位...
- python对网站DDos攻击
- Postgresql - 监控 moniter — pgbadger
- uni-app使用多彩色图标,阿里图库
- 数独项目Last弹:网络识别PIAN
- 流放者柯南rust_《流放者柯南》评测8.0分 胯下生风的沙盒生存游戏
- 自动驾驶决策规划算法第一章笔记 忠厚老实的老王
- 【小程序】爆肝 3 天总结的微信小程序优化指南(收藏夹吃灰吧!)
- CSC与HPE企业服务合并后新名称公布:DXC Technology
- 浅谈百度谷歌蜘蛛机器人活动规律