UE5.8 Smart Objects 专题系列

UE5.8 Smart Objects 专题(六):蓝图、C++、EQS 和 Behavior Tree 怎么用

整理普通 AI 项目最常用的 Smart Object 使用路径:蓝图函数、C++ API、EQS Generator、Blackboard ClaimHandle 和 BTTask_FindAndUseGameplayBehaviorSmartObject。

总览

如果你不是在做 Mass 人群,最常见的接入方式有三种:蓝图直接调 SmartObjectSubsystem,C++ 写自己的交互任务,Behavior Tree 用 EQS 找点再执行行为。哪种都可以,但生命周期必须一致:Find 只是候选,Claim 才是占位,Occupied 才是使用,结束必须 Free。

UE5.8 Smart Objects 专题(六):蓝图、C++、EQS 和 Behavior Tree 怎么用 配图
普通 AI 项目优先用 C++/蓝图/EQS/Behavior Tree 把 Smart Object 闭环跑稳,再接更复杂系统。

蓝图路径

蓝图里通常这样拆:AI 触发“找椅子”事件,构造请求范围和 Filter,调用 Find Smart Objects,选一个结果,Claim,MoveTo Slot Transform,开始行为,行为结束释放。蓝图适合做验证和简单 AI,但生产项目建议把 Claim/Release 封成 C++ 节点,避免每个蓝图都漏 Abort 清理。

C++ 路径

C++ 最适合写通用 UAITaskUAbilityTask。任务持有 FSmartObjectClaimHandle,在 Activate 里查询和 Claim,在 MoveTo 成功后 Occupy,在 OnDestroy 或 Cancel 里释放。这样不管行为树 Abort、能力取消还是角色死亡,清理都能进同一条路径。

void UMyUseSmartObjectTask::AbortAndRelease()
{
    if (ClaimHandle.IsValid())
    {
        if (USmartObjectSubsystem* Subsystem = USmartObjectSubsystem::GetCurrent(GetWorld()))
        {
            Subsystem->MarkSlotAsFree(ClaimHandle);
        }
        ClaimHandle.Invalidate();
    }
}

EQS 路径

UEnvQueryGenerator_SmartObjects 会从 Query Origin 出发,用 QueryBoxExtent 找 Smart Object Slot。配置 SmartObjectRequestFilter 后,你可以继续用 EQS 的距离、路径、可见性测试排序。它有 bOnlyClaimable,适合过滤掉已经不可 Claim 的 Slot。

EQS 的好处是策略清晰:Smart Object 负责“哪些点合法”,EQS 负责“哪个点最好”。比如找掩体时,Smart Object 只筛出 Activity.Cover,EQS 再按敌人方向、路径长度、遮挡质量排序。

Behavior Tree 路径

UBTTask_FindAndUseGameplayBehaviorSmartObject 是开箱即用的 BT Task。它有 ActivityRequirementsClaimPriority、EQS 请求和 Fallback Radius。任务会查找 Smart Object,并用 UAITask_UseGameplayBehaviorSmartObject 执行对应 GameplayBehavior。

如果你希望自己控制 MoveTo、朝向、动画和释放,更建议拆成三个 BT Task:FindAndClaim、MoveToSmartObject、UseAndRelease。这样每一步都能在黑板上看见 ClaimHandle、Slot Transform 和失败原因。

使用案例

守卫下班流程:Behavior Tree 进入 Rest 分支,EQS 找 Activity.Sit,Claim 椅子,MoveTo 椅子入口,执行 GameplayBehavior 坐下。收到警报时 BT Abort,任务释放 Claim,守卫切回警戒。这个案例能覆盖查询、占用、中断和行为执行。

架构分析

Behavior Tree 版本把很多细节封装了,适合上手;C++ 版本可控性高,适合项目统一封装;EQS 版本适合做“多候选排序”。三者不是互斥关系。一个成熟项目常常是:EQS 做候选,C++ Task 统一生命周期,BT/StateTree 负责决策。

项目落地

给 AI 程序提供一个统一组件或库:FindSmartObjectByActivityClaimSmartObjectGetClaimedSlotTransformUseSmartObjectReleaseSmartObject。蓝图只调用高层节点,不直接拼 Subsystem 的所有细节。

常见坑

  • BT Task Abort 不释放:这是最常见的“椅子被占死”来源。
  • EQS 只排序不 Claim:EQS 结果只是候选。
  • Blackboard 保存 RequestResult 而不是 ClaimHandle:跨帧使用需要 ClaimHandle。
  • MoveTo 目标用对象 Actor Location:应该用 Slot 或 Entrance Transform。
  • 客户端蓝图直接改状态:多人项目里占用和释放应由服务器主导。

源码依据

UEnvQueryGenerator_SmartObjects 提供 EQS Generator,参数包括 QueryOriginContextFSmartObjectRequestFilterQueryBoxExtentbOnlyClaimableUBTTask_FindAndUseGameplayBehaviorSmartObject 保存 ActivityRequirements、ClaimPriority、EQSRequest 和 Fallback Radius。UBlackboardKeyType_SOClaimHandle 提供黑板 ClaimHandle 类型。

源码路径索引

  • SmartObjectsModule/Public/SmartObjectBlueprintFunctionLibrary.h
  • SmartObjectsModule/Public/EnvQueryGenerator_SmartObjects.h
  • SmartObjectsModule/Public/BlackboardKeyType_SOClaimHandle.h
  • GameplayBehaviorSmartObjectsModule/Public/AI/BTTask_FindAndUseGameplayBehaviorSmartObject.h
  • GameplayBehaviorSmartObjectsModule/Public/AI/AITask_UseGameplayBehaviorSmartObject.h