UE AI系统
架构
Enemy 告诉 AI Controller 使用行为树组件的哪个行为树,然后行为树组件启动并运行(AI Controller 上调用)该行为树
行为树
执行逻辑时,行为树会使用一种名为 黑板 的独立资源来存储它需要知道的信息(名为 黑板键),从而做出有根据的决策。常见工作流程是创建一块黑板,添加一些黑板键,然后创建一个使用黑板资源的行为树。
运行前提:
- Pawn 关联 AIController
- AIController 中, 当该控制器”Possess”此Pawn时,运行一个行为树:
- 关卡中寻路需要添加 NavMesh
执行顺序:从左到右,从上到下(中左右)
节点右上角的数字,表示操作的顺序
蓝色节点被称为装饰器节点(在其他行为树系统中被称为 条件语句_)。它连接到一个合成节点,用于验证该黑板键是否为 true。这决定了该分支的其余部分是否能够执行。
紫色节点是任务(Task)节点,是AI可以完成的动作。
特点:(与传统行为树的比较)
- 行为树由事件驱动,被动地监听可用于触发树中变化的”事件”,避免每帧进行不必要的共工作。
- 条件语句并非叶节点,而是装饰器(Decorator)节点。所有叶节点都是操作任务节点。条件语句装饰器的另一个优点是可以轻松将装饰器设为树中关键节点上的观察者(等待事件)。要充分利用树事件驱动的特点,此特性十分关键。
- 使用简单平行节点(服务节点),以及装饰器节点的 观察者中止(Observer Aborts) 属性来处理并发行为。
合成节点 Composite
[!NOTE] 合成节点
主要作用:流程控制
是流控制的一种形式,决定了与其相连的子分支的执行方式。
只有 合成 节点可以连接至 行为树 的 Root 节点。
合成节点 | 描述 |
---|---|
选择器(Selector ) |
从左到右顺序执行其子节点。当其中一个子节点执行成功时,选择器节点将停止执行。 如果选择器的一个子节点成功运行,则选择器运行成功。如果选择器的所有子节点运行失败,则选择器运行失败。 |
序列(Sequence ) |
从左到右的顺序执行其子节点。当其中一个子节点失败时,序列节点也将停止执行。 如果有子节点失败,那么序列就会失败。如果该序列的所有子节点运行都成功执行,则序列节点成功。 |
简单平行(Simple Parallel ) |
简单平行节点有两个”连接”。 第一个是主任务,它只能分配一个任务节点(意味着没有合成节点)。 第二个连接是后台分支:是主任务仍在运行时应该执行的活动。 简单平行节点可能会在主任务完成后立即结束,或者等待后台分支的结束,具体依属性而定。 |
可以将简单平行节点理解为”执行 A 的同时,也在执行 B”。例如”攻击敌人,同时也朝敌人移动。”从基本上而言,A 是主任务,B 是后台分支。
装饰器节点 Decorator
[!NOTE]
主要作用:对子树的返回结果进行处理
条件语句,连接到合成(Composite)或任务(Task)节点,并定义树中的分支,甚至单个节点是否可以执行。
- Composite:合成,自定义逻辑。以这种方式使用合成装饰器将影响内存和性能。也可以在C++中创建一个装饰器来执行同样的自定义行为,但效率更高。
- Blackboard:检查给定的 黑板键(Blackboard Key) 上是否设置了值。
- Check Gameplay Tags on Actor:检查 Gameplay Tag
- Compare BBEntries:比较两个 黑板键 的值,并根据结果(等于或不等)阻止或允许节点的执行。
- Conditional Loop:条件语句循环,只要满足了 键查询(Key Query) 条件,该装饰器将使它所连接节点进行循环。
- Cone Check:椎体检查装饰器,采用了三个矢量键:第一个确定椎体的起始位置,第二个用于定义锥体朝向的方向,第三个用于检查该位置是否在锥体内部。您可以使用 锥体半角(Cone Half Angle) 属性来定义锥体的角度。
- Cooldown:冷却装饰器, 将锁定节点或分支的执行,直到冷却时间结束。
- Does Path Exist:路径是否存在,会检查是否可以在以下两个矢量之间创建路径:黑板键A和黑板键B
- Force Success:强制成功装饰器,会将节点结果更改为成功。
- Is at Location:在位置处装饰器,节点将检查 AI 控制的 Pawn 是否位于给定位置。
- ls BBEntry Of Class:用于确定所指定的黑板键是否属于指定的类。
- Keep in Cone:保持在椎体内装饰器,节点会根据所观察到的位置是否仍位于锥体内部来确定其条件。当节点首次拥有相关性时,将计算锥体的方向。
- Loop:对节点或分支进行多次循环或无限次循环。
- Set Tag Cooldown:设置 GameplayTag 的冷却时长。
- Tag Cooldown:基于 GameplayTag 的冷却计时器是否过期。
- Time Limit:时间限制装饰器,会为一个分支或节点设置在终止其运行并失败前,完成运行所需的一段时间。每当该节点被聚焦时,计时器都会重置。
服务节点 Service
服务节点:服务节点是与任意合成节点(选择器节点、序列节点或简单平行节点)相关联的一种特殊节点。只要在合成节点的分支被执行,它们就会以定义的频率执行。常用于检查和更新黑板。
它能够针对指定秒数的每个回调进行注册,并能对多种需要周期性出现的类型进行更新。
举例而言,当 AI Pawn 面对当前敌人、继续在其行为树中正常行动时,可以使用服务节点为该 Pawn 确定最适合追逐的敌人。
- 默认聚焦(Default Focus) 通过设置控制器的聚焦来创建访问 蓝图 和代码中 Actor 的快捷方式。将 AIController 的聚焦设置到 Actor 上后,你便能直接从 AI 控制器对其进行访问,而不需要访问黑板键。
- 运行 EQS(Run EQS) 服务节点可用于以指定的时间间隔定期执行场景查询系统(EQS)模板,并可对指定的黑板键进行更新。
任务节点 Tasks
任务节点的功能是实现操作,例如移动 AI 或调整黑板值。它们可以连接至装饰器节点或服务节点。
- Finish with Result:以结果完成 任务节点可用于在完成时即时输出一个给定结果。该节点会基于所定义的结果强制分支结束或继续。
- Make Noise:如果受控Pawn拥有 PawnNoiseEmitter 组件,发出噪音(Make Noise) 任务将使Pawn”产生噪声”(发送消息),使其它拥有 PawnSensing 组件的Pawn听到(接收消息)。
- Move Directly Toward:直接移动至任务节点会将 AI Pawn 沿直线移向指定的 Actor 或位置(矢量)黑板条目,而不参考任何导航系统。如果需要 AI 按导航移动,请改用 移动至(Move To) 任务节点。
- Move To:移动至任务将使拥有角色移动组件的Pawn使用NavMesh移动至矢量黑板键。
- Play Animation:用于播放指定的动画资源。
- Play Sound:播放指定的音效。
- Push Pawn Action:推送 Pawn 动作节点使您能够将指定的动作推送至 Pawn 的控制器。
- Rotate to Face BBEntry:旋转至面向黑板条目任务节点会使关连 Pawn 向指定的黑板键旋转。( Pawn 必须启用 Use Controller Rotation Yaw )
- Run Behavior:运行行为任务节点将分支树推送到执行堆栈上,从而运行另一个行为树。(给子树的根等级装饰器节点提供支持。在运行时不能改变该子树资源,在运行时不能修改运行树的结构。如果您需要在运行时能修改的子树,使用 Run Behavior Dynamic)
- Run Behavior Dynamic:运行动态行为任务节点能够在执行堆栈上推送子树。使用 行为树组件 上的 SetDynamicSubtree 函数即可以在运行时分配子树资源。(本函数不会为子树的根等级装饰器节点提供支持。)
- Run EQSQuery:将运行指定的场景查询系统(EQS)资源。
- Set Tag Cooldown:设置 冷却标签(Cooldown Tag) 数值,并与 冷却标签装饰器(Cooldown Tag Decorators) 一起使用,从而防止行为树的执行。
- Wait:使树在此节点上等待,直至指定的 等待时间(Wait Time) 结束。
- Wait Blackboard Time:与 等待(Wait) 任务节点的原理类似,由黑板键盘指定时间
观察者中止 Observer Aborts
传统行为树的标准平行节点的一个常见用处是不断检查条件。一旦任务所需的条件变成 false,该任务就可以中止。
举例而言,有一只猫在执行序列节点(例如”发出嘶声”和”扑击”)。如果老鼠逃入洞里,则需要猫立即放弃。如果使用平行节点,你要设置一个子项检查是否可以扑击老鼠,然后设置另一个子项检查序列要执行的动作。
因为虚幻引擎行为树由事件驱动,所以我们要解决此问题。可以通过条件装饰器观察其数值,并且在必要时中止。在本例中,可以在序列上设置”是否可以扑击老鼠?(Mouse Can Be Pounced On?)”装饰器节点,把”观察者中止(Observer Aborts)”设置为”自身(Self)”。
在行为树中,观察者中止(ObserverAborts)是我们控制任务节点执行的最重要的设置之一,其能在满足装饰器节点临界条件后有条件地中止被观察者中止标记为中止范围的所有节点的执行。
观察者中止有两个重要的参数,Notify Observer与Observer Aborts
Notify Observer (通知观察者):
控制BT如何通知观察者中止,鉴于观察者中止的控制是bool类型,一般使用On Result Change即可。
- On Result Change:对应装饰器节点的 Bool 结果发生变化时通知中止。
- 这里的”结果”指的是行为树节点的执行结果。行为树节点的执行结果通常是一个布尔值,表示节点的执行状态。例如装饰器节点:
当 Key 没有 Set 时,
就会失败返回 false。
- 这里的”结果”指的是行为树节点的执行结果。行为树节点的执行结果通常是一个布尔值,表示节点的执行状态。例如装饰器节点:
- On Value Change:对应装饰器节点的值(一般是行为树对应的黑板中装饰器节点使用的黑板键的值)变化时通知中止。
Observer Aborts(观察者中止):
主要控制观察者中止对中止范围的标识。即,在通知中止后,中止中止范围内的执行中节点,并转而执行观察者中止标识的行为树节点或子树。
- None 不中止执行。
- Self 中止此节点自身和在其下运行的所有子树。
- Lower Priority 中止此节点右侧的所有节点(低优先级,即序号更高的)。
- Both :中止 Self+Lower Priority
[!NOTE]
执行中节点不在中止范围时观察者中止无效。
观察者中止的中止将会按照行为树的最短距离进行中止转换控制。即,行为树将从执行中节点向上回溯到该执行中节点与观察者中止标识节点或子树的最深共同父级,再从此父级向下顺序执行,并仍然判断 BTD 的可执行性。也即,观察者中止并不会从 Root 开始重新执行整个行为树,其行为逻辑接近节点跳转。
行为树节点实例化规则
行为树节点作为共享对象存在,这意味着使用同一行为树的所有代理将共享一组节点实例。这样不仅可以在降低内存使用率的同时提升 CPU 性能,还可以防止节点保存代理特定的数据。
不过,对于代理需要存储和更新节点相关信息的情况,虚幻引擎提供了以下三种解决方案:
实例化节点
将节点的 bCreateNodeInstance
变量设为 true
后,将使每个使用行为树的代理成为特殊的节点实例,以牺牲一定性能和内存使用率为代价来确保安全存储代理专属的数据。
包括 UBTTask_BlueprintBase
、UBTTask_PlayAnimation
、UBTTask_RunBehaviorDynamic
在内的部分虚幻引擎节点类均使用此功能。
存储在黑板上
常见的解决方案是将变量存储在黑板上。执行此操作的方法是从节点公开变量命名,然后在节点初始化过程中使用该命名获取和存储黑板键。然后便可以使用黑板键在代理的黑板实例上获取并设置该变量的值。此方法支持 bool
、float
、FVector
、int32
、enum
(存储为 uint8
)、UObject*
类型的变量。
存储在行为树节点上
可以创建自定义结构体或类,将变量存储在节点的内存中。例如,UBTTask_MoteTo
类利用 FBTMoveToTaskMemory
。
您可以在 BTTask_MoteTo.h
中找到以下代码:
1 | struct FBTMoveToTaskMemory |
UBTNode
中的许多虚函数都将 uint8*
参数带到节点的内存中。此参数指示为代理分配的内存块,内存块大小将由 GetInstanceMemorySize
的覆盖版本返回。节点将为各个代理分配此大小的内存,并将此内存存储到单一连续块中,以优化性能。但此内存不属于 UObject 生态系统,也不属于虚幻引擎的反射系统,且无法通过垃圾回收查看。因此,UPROPERTY
支持将不可用,建议使用 TWeakObjectPtr
来存储可能需要的 UObject
指针。
AI 感知系统
除可用于决定所执行逻辑的行为树,以及用于获取环境信息的场景查询系统(EQS)之外,AI 框架中可用于为 AI 提供感官数据的另一个工具是 AI 感知系统(AI Perception System) 。通过 AI 感知组件实现。
AIPerception 感知组件
AI 组件允许 Pawn 感知周围环境中的数据,例如噪声来源位置、或 Pawn 能够看到某个对象。
AIPerception
组件相当于刺激源的监听器,用于收集已注册的刺激信号。AI Perception Stimuli Source
组件自动将 Actor 注册成为感知系统中指定感官的一个刺激源。- 刺激源被注册后将调用 AIPerception 组件的
On Perception Updated
(或用于目标选择的On Target Perception Updated
)事件
感知配置
可以配置多个感官,并且指定一个主导感官(Dominant Sense),该感官应优先于其他感官。
Al Damage sense config 伤害:对伤害事件(如 Event Any Damage 、 Event Point Damage 或 Event Radial Damage )作出反应。
Al Hearing config 听觉:检测由 报告噪点事件(Report Noise Event) 产生的声音,例如发射物击中某物发出的声音
Al Prediction sense config 感知 :这要求感知系统(Perception System)在 PredictionTime 秒内向请求者提供 PredictedActor 的预计位置。
Al Sight config 视觉:决定着 AI 角色在关卡中所能”看见”的事物。当一个 Actor 进入 视觉半径 后,AI 感知系统将发出更新信号,并穿过被看到的 Actor(举例而言,一个玩家进入该半径,并被具备视觉感知的 AI 所察觉)。
Al Team sense config 团队:通知感知组件的拥有者同团队中有人处在附近(发送该事件的游戏代码也会发送半径距离)。
Al Touch config 触觉:检测到 AI 与物体发生主动碰撞,或是与物体发生被动碰撞。举例而言,在潜入类型的游戏中,你可能希望玩家在不接触敌方 AI 的情况下偷偷绕过他们。使用此感官可以确定玩家与 AI 发生接触,并能用不同逻辑做出响应。
Detection by Affiliation 从属检测:默认情况下 Actor 不会被指定归属,会被视为中立(neutrals)。
[!NOTE]
目前,你还不能通过蓝图分配归属,因此为了检测玩家,我们要启用 检测中立(Detect Neutral) 标签。另外一种方法是使用 Actor 标签(Actor Tagging) 来确定哪个角色是玩家,并强制 AI 角色只追逐被标记为玩家的 Actor。
感知函数调用
以下函数可以通过蓝图调用,进而从感知系统获取信息,或对感知系统产生影响。
函数 | 描述 |
---|---|
Get Actors Perception | 获取针对给定Actor的感知,并返回被感知Actor的数据结构。 |
Get Currently Perceived Actors | 返回基于给定感官被感知的全部Actor。如果未指定感官,则返回当前以任意方式感知到的所有Actor。 |
Get Known Perceived Actors | 返回基于给定感官被感知的(且尚未被遗忘)的所有Actor。如果未指定感官,则被感知到的所有Actor均将被返回。 |
Get Perceived Hostile Actors | 返回敌方Actor列表(发出的刺激已被感知且未失效或已成功感知的所有敌方Actor)。本方法可以在蓝图中重写,返回用户所需的任意Actor列表。 |
Request Stimuli Listener Update | 手动强制AI感知系统更新指定目标的刺激监听器的属性。 |
Set Sense Enabled | 启用或禁用指定的 感官类 。 只有在针对目标组件实体配置给定感官后,该设置才有效。 |
刺激源配置
还可以指定基于 AISense 类的所有自定义感官。
刺激函数调用
以下函数可以通过 AI 感知刺激源 组件的蓝图调用:
函数 | 描述 |
---|---|
注册为感官(Register for Sense) | 将拥有Actor注册为指定感官类的刺激源。 |
注册到感知系统(Register with Perception System) | 将拥有Actor注册为 注册为感官源(Register as Source for Senses) 属性中所指定感官的刺激源,并通过 Register for Sense 函数调用。 如果启用了自动注册为源(Auto Register as Source)属性,则不需要调用此函数。 |
从感知系统中注销(Unregister from Perception System) | 取消将拥有Actor注册为感知刺激源。 |
从感知中注销(Unregister from Sense) |
PawnNoiseEmitter 噪声发射器组件
PawnNoiseEmitterComponent
追踪 PawnSensingComponents
使用的噪声事件数据来监听 Pawn。该组件主要存在于 Pawn 或其控制器上。它在网络客户端上不进行任何操作。
PawnSensing 感应组件
Pawn 的感应组件(Sensing Component
)用于封装 Actor 的感知(例如视觉和听觉)设置及功能,以便 Actor 在游戏世界中观察/监听 Pawn。其在网络客户端上不进行任何操作。
在蓝图中可视化设置感官的范围:
注意视锥体的调整有两项:半径和角度
寻路系统
虚幻引擎寻路系统 用于为人工智能代理(AI Agent)提供寻路功能。
为了帮助AI确定起点和终点之间的路径,引擎会根据场景中的碰撞体生成寻路网格体。这种简化的多边形网格体代表了关卡中的可寻路空间。默认情况下,寻路网格体会细分为多个区块,允许你重新构建寻路网格体的局部区域。
生成的网格体由多个多边形组成,每个多边形都有一个”成本”值。搜索路径时,寻路算法会尝试找到总成本最低的路径。
寻路系统包含各种组件以及可修改寻路网格体生成方式的设置,例如指定给多边形的成本。这进而影响代理在你的关卡中寻路的方式。你还可以将寻路网格体中不连续的区域连接起来,如平台和桥梁。
寻路系统包含三种 生成模式(Generation Modes):静态(Static)、动态(Dynamic) 和 仅限动态修改器(Dynamic Modifiers Only)。这些模式控制了项目中生成寻路网格体的方式,并提供了各种选项来满足你的需要。
项目设置—引擎网格体—运行时
该系统还为代理提供了两种规避方法:相对速度障碍物(RVO)(Reciprocal Velocity Obstacles (RVO)) 和 大规模人群绕行避让管理器(Detour Crowd Manager)。这些方法允许代理在游戏过程中绕行,避让动态障碍物和其他代理。
注意寻路网格体在楼梯上无法正确绘制,可以调整绘制偏移让覆盖面更广。
重要节点(由事件驱动):
修改寻路系统
- 寻路修饰体积
:使用区域类(Area class)来确定体积内寻路的 默认成本(Default Cost) 乘数。从而改变特定区域中的 Nav Mesh 成本,让指定区域可达或不可达。
[!NOTE] 区域类
- 区域类还定义了 固定区域进入成本(Fixed Area Entering Cost),这是代理进入该区域时采用的初始成本。你可以根据需要创建任意数量的区域类来影响代理如何寻路关卡。
- 可以创建 Area Class 蓝图自定义区域类
- 寻路查询筛选器(Navigation Query Filters): 包含有关一个或多个区域类的信息,如有需要,可以重载成本值。你可以根据需要创建任意数量的查询筛选器来进一步自定义代理如何寻路关卡。自定义寻路区域和查询筛选器
- 寻路链接代理
:能将寻路网格体中没有直接寻路路径的两个区域连接起来。在搜索路径的同时,寻路链接代理会用作额外连接,供代理用于到达目的地。
- 自定义蓝图,使用智能链接代理以允许代理在平台之间朝着目标跳跃或执行其他动作教程链接
- 自定义蓝图,在运行时动态生成 Nav Mesh教程链接
避障机制
在虚幻引擎寻路系统中使用避障机制 | 虚幻引擎5.2文档 (unrealengine.com)
寻路机制可以在静态对象周围生成路径,而避障算法主要用于处理移动障碍物。
AI 代理有两种方法来绕开移动障碍物,或在彼此间避障,分别是 相对速度障碍物算法(Reciprocal Velocity Obstacles,即 RVO) 和 群组绕行管理器(Detour Crowd Manager)。
相对速度障碍物算法 系统会计算每个代理的速度向量,避免和附近的其他代理碰撞。该系统会查看附近的代理,并假定它们在计算的每一步内都以恒速移动。根据代理向目标移动的速度,会选择最佳的速度向量进行匹配。
- RVO 不使用寻路网格体进行避障,因此它无需寻路系统即可用于代理。该系统包含在角色类的 角色移动(Character Movement) 组件中。
- RVO 不使用寻路网格体进行避障,因此它无需寻路系统即可用于代理。该系统包含在角色类的 角色移动(Character Movement) 组件中。
群组绕行管理器(Detour Crowd Manager) 系统通过自适应 RVO 采样计算来解决代理之间的规避问题。它会计算一个粗略的速度采样,并且着重在代理的移动方向,相较于传统的 RVO 规避方式,显著提升规避性能。该系统还使用可见度和拓扑路径优化项,进一步提升碰撞规避。
- 群组绕行管理器系统可以高度配置特定示例模式选项、最大代理数和代理半径。该系统包括在 群组绕行 AI 控制器(DetourCrowd AI Controller) 类中,可以和任意 Pawn 类一起使用。
两种系统各自独立工作,在你的项目中只能使用其中一种。
方法 | 描述 | 局限性 |
---|---|---|
相对速度障碍物算法 | - 代理使用特定半径内的速度向量规避障碍物。 - 包含在角色类的角色移动(Character Movement)组件中。 |
- 相较于群组绕行管理器更难配置。 - 仅限于角色类中。 - 不使用寻路网格体进行规避,因此代理可能会任性地”出走”。 |
群组绕行管理器 | - 代理通过路径优化和特定半径内的速度向量规避障碍物。 - 包含在群组绕行AI控制器(DetourCrowd AI Controller)类中。| 在项目设置中定义了固定的最大代理数量。 |
- 在项目设置中定义了固定的最大代理数量。 |
寻路调用程序
寻路调用程序(Navigation Invokers) 是在运行时在代理周围生成寻路网格体的蓝图 Actor 组件。使用寻路调用程序,就无需在编辑器中构建寻路网格体,并且还可以限制在运行时生成的图块数。
寻路调用程序非常适合大型关卡,因为在编辑器中构建寻路网格体不切实际。
使用虚幻引擎中的寻路调用程序 | 虚幻引擎5.2文档 (unrealengine.com)
优化 NavMesh 生成速度
优化虚幻引擎寻路网格体的生成速度 | 虚幻引擎5.2文档 (unrealengine.com)
世界分区静态导航网格
世界分区导航网格 | 虚幻引擎5.2文档 (unrealengine.com)
MassEntity(鸽)
MassEntity 是一个重点围绕游戏逻辑打造的框架,用于面向数据的计算。基于 ECS
虚幻引擎MassEntity | 虚幻引擎5.2文档 (unrealengine.com)
智能对象(鸽)
智能对象(Smart Object) 是可以放置在关卡中与AI代理和玩家交互的对象。这些对象包含交互所需的所有信息。
虚幻引擎智能对象概述 | 虚幻引擎5.2文档 (unrealengine.com)
StateTree(鸽)
StateTree 是一种通用分层状态机,组合了行为树中的 选择器(Selectors) 与状态机中的 状态(States) 和 过渡(Transitions) 。使用 StateTree,你可以创建非常高效、保持灵活且井然有序的逻辑。
虚幻引擎中的StateTree | 虚幻引擎5.2文档 (unrealengine.com)
环境查询系统 EQS
场景查询系统(EQS)用于从环境中收集数据,获取环境信息。在 EQS 中,可以通过不同种类的测试向收集的数据提问,这些测试会根据提出问题的类型来生成最适合的项目。
- 场景查询系统(EQS) 可在行为树中用于通过各种轮询测试场景,然后根据这些测试的结果做出如何继续的决定。EQS 的一些样板用例包括:让 AI 角色找到避开玩家视线的掩护位置,或者找到关卡中最近的体力回复剂或弹药。
生成器生成位置(黄色圆圈 ),然后使用 Trace 和 Distance 测试,就能知道能看到 Player 且最近的位置。这样 Enemy 就能移动到该位置并发现Player
节点类型 | 描述 |
---|---|
Generator 生成器 |
生成位置或Actor,称为 项目(Item),将被测试和加权。 |
Context 上下文 |
这是各种测试和生成器的参考框架 上下文可以是简单的 Querier查询器(其执行测试),也可以是比较复杂的Item,例如 某种类型的所有Actor |
Test 测试 |
这是场景查询系统确定来自生成器的项目(Item)是否为”最佳”选项的方式。 以对一个生成器添加多个测试,这是缩小结果范围的有效方法,可以提供尽可能好的选择。 |
从行为树调用场景查询(任务节点),然后实际的场景查询将使用其 Generator,引用其 Context,并使用其 Test
对生成的数据提问,返回符合所提问题类型的最佳 Item(作为黑板键返回,是权重最高的结果)
[!NOTE] 节点注意事项
- 虽然可以将多个生成器连接到 Root,但查询中只会使用最左侧的生成器。
- 对生成器添加 Test 的顺序并不重要。Test 会自动排序,将过滤 Test 排在前面(从而使后续测试所处理的项目(Item)集合尽可能小),还会按开销过滤(从而使距离过滤器在视线过滤器之前执行)。
调式工具
AI调试工具查看任何活动的 EQS 查询(除了行为树或感知信息之外)。要在运行时激活 AI 调试,请按 **’**(撇号)键,然后选择1(进行一般 AI 调试)、2(用于行为树)、3(用于 EQS)或4(用于 AI 感知)。下面我们激活 AI 调试并调出 EQS 调试工具。
除了使用 EQS 调试工具外,还有一种特殊类型的 Pawn,叫做 EQS 测试 Pawn,可用于在编辑器中调试 EQS 查询。你可以通过创建新蓝图类 EQS Testing Pawn 类来创建此 Pawn。
我们的当前设置使用玩家角色作为情境,用于在我们的 EQS 测试中求值。要在游戏未运行时测试,我们需要对 EQS_PlayerContext 蓝图稍加修改,覆盖 Provide Actors Set 函数。
我们可以使用 获取所有(Get All Actors of Class),将其设为 ThirdPersonCharacter,这会提供 结果 Actor 集(Resulting Actors Set):
将EQS测试Pawn添加到关卡时,在 细节(Details) 面板中可以指定 查询模板(Query Template)(我们已将它设为我们的 EQS_FindPlayer 查询)。
这样当你在编辑器中时,就可以看到测试的结果,如下图所示:
系统还会通过VisLog记录EQS数据供你参考。请参见 Visual Logger 了解更多信息。