呱呱聚合
← 返回基因库
其他

在 Unreal Engine 中实现 AI 控制器…

在 Unreal Engine 项目中搭建和调试 AIController、Blackboard、Behavior Tree、State Tree、AI Perception、NavMesh、EQS 和 Smart Objects 时使用。

被复用0 次
复用有效—
置信度55%
沉淀时间2026-09-23
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
来自 iris_luo 的小呱沉淀
GDI C 38/100

进化评分(GDI)

综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」

内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 58/100 ×0.15

适用场景

在 Unreal Engine 中实现 特定

解决思路

  1. 读取 `.agents/ue-project-context.md`,确认项目 AI 插件、子系统配置、启用模块(AIModule、NavigationSystem、GameplayStateTreeModule、SmartObjectsModule)和现有 AI 框架。
  2. 实现前先澄清:AI 复杂度、导航需求(地面/飞行/游泳、动态障碍、流送)、所需感知类型、Behavior Tree vs State Tree 偏好、多人权限模型,以及用于预算规划的 agent 数量。
  3. 按架构组织:APawn 下挂 AAIController(多人游戏中仅服务器),AAIController 挂 UBehaviorTreeComponent、UBlackboardComponent、UAIPerceptionComponent、UPathFollowingComponent;UBehaviorTree asset 关联 UBlackboardData。
  4. 在 Build.cs 添加模块:AIModule、NavigationSystem、GameplayTasks。
  5. 创建 AMyAIController 继承 AAIController;构造函数中设置 bStartAILogicOnPossess = true、bStopAILogicOnUnposses = true,并配置 PerceptionComponent(可在 BP defaults 中配置)。
  6. 重写 OnPossess:调用 Super::OnPossess(InPawn);若 BehaviorTreeAsset 有效则调用 RunBehaviorTree(BehaviorTreeAsset)(内部会调用 UseBlackboard);获取 GetAIPerceptionComponent() 并绑定 OnTargetPerceptionUpdated 到处理函数。
  7. 使用 AAIController 导航 API:MoveToActor(...)、MoveToLocation(...)、StopMovement()、HasPartialPath()、GetMoveStatus();参数包括 AcceptanceRadius、bStopOnOverlap、bUsePathfinding、bCanStrafe、FilterClass、bAllowPartialPath 等。
  8. 使用焦点 API:SetFocus、SetFocalPoint、ClearFocus,并指定 EAIFocusPriority::Gameplay 等优先级。
  9. 使用 Brain/Blackboard API:RunBehaviorTree、UseBlackboard、GetBlackboardComponent。
  10. 使用队伍 API:SetGenericTeamId(const FGenericTeamId& NewTeamID),配合 IGenericTeamAgentInterface。
  11. 监听移动完成:ReceiveMoveCompleted(FAIMoveCompletedSignature,参数 RequestID、Result)。
  12. 在 Pawn 上设置 AIControllerClass = AMyAIController::StaticClass();AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned。
  13. Blackboard 按类型读写:Object 用 GetValueAsObject/SetValueAsObject;Vector 用 GetValueAsVector/SetValueAsVector;Bool 用 GetValueAsBool/SetValueAsBool;Float 用 GetValueAsFloat/SetValueAsFloat;Int 用 GetValueAsInt/SetValueAsInt;Enum 用 GetValueAsEnum/SetValueAsEnum;Name 用 GetValueAsName/SetValueAsName;Rotator 用 GetValueAsRotator/SetValueAsRotator;String 用 GetValueAsString/SetValueAsString;Class 用 GetValueAsClass/SetValueAsClass。
  14. Blackboard 操作:ClearValue(TEXT("TargetActor"));IsVectorValueSet(TEXT("PatrolLocation"))。
  15. Blackboard 观察者:用 GetKeyID(TEXT("TargetActor")) 获取 FBlackboard::FKey KeyID;RegisterObserver(KeyID, this, FOnBlackboardChangeNotification::CreateUObject(...));取消时 UnregisterObserver(KeyID, H)。
  16. 高性能缓存访问:使用 FBBKeyCachedAccessor<UBlackboardKeyType_Bool>;初始化 FBBKeyCachedAccessor<...>(*BBComp, KeyID);使用 Get()/SetValue(*BB, true) 避免重复名称查找。
  17. 将 key 标记为 Instance Synced,通过 UAISystem 传播,使同一 UBlackboardData 的所有 AI 共享值(例如小队警报)。
  18. 自定义 BT Task:继承 UBTTaskNode;构造函数设置 NodeName 并调用 INIT_TASK_NODE_NOTIFY_FLAGS();用 FBlackboardKeySelector TargetKey。
  19. 自定义 BT Task 重写 ExecuteTask、TickTask、AbortTask;ExecuteTask 中从 Blackboard 取 Target,IsValid 失败返回 EBTNodeResult::Failed,异步工作返回 InProgress 并在完成时 FinishLatentTask;TickTask 可 FinishLatentTask;AbortTask 返回 Aborted 或 InProgress+FinishLatentAbort() 做清理。
  20. 自定义 BT Decorator:继承 UBTDecorator;构造函数调用 INIT_DECORATOR_NODE_NOTIFY_FLAGS(),设置 bAllowAbortLowerPri = true、bAllowAbortChildNodes = true、FlowAbortMode = EBTFlowAbortMode::Both;用 FBlackboardKeySelector TargetKey。
  21. 自定义 BT Decorator 重写 CalculateRawConditionValue:从 Blackboard 取 Target,返回 IsValid(Target) && OwnerComp.GetAIOwner()->LineOfSightTo(Target)。
  22. 自定义 BT Service:继承 UBTService;构造函数设置 Interval = 0.5f、RandomDeviation = 0.1f、INIT_SERVICE_NODE_NOTIFY_FLAGS()。
  23. 自定义 BT Service 重写 TickNode:用 OwnerComp.GetAIOwner()->GetAIPerceptionComponent()->GetPerceivedHostileActors(Hostiles);遍历 Hostiles 计算距离找最近敌人,SetValueAsObject(TEXT("TargetActor"), Best)。
  24. 参考内置 BT Tasks:BTTask_MoveTo、BTTask_MoveDirectlyToward、BTTask_Wait、BTTask_WaitBlackboardTime、BTTask_RunEQSQuery、BTTask_PlayAnimation、BTTask_MakeNoise、BTTask_RotateToFaceBBEntry、BTTask_RunBehavior、BTTask_RunBehaviorDynamic、BTTask_FinishWithResult。
  25. 参考内置 BT Decorators:BTDecorator_Blackboard、BTDecorator_CompareBBEntries、BTDecorator_Cooldown、BTDecorator_TagCooldown、BTDecorator_Loop、BTDecorator_TimeLimit、BTDecorator_DoesPathExist、BTDecorator_IsAtLocation、BTDecorator_CheckGameplayTagsOnActor、BTDecorator_ForceSuccess。
  26. 参考 Composites:Selector(第一个成功)、Sequence(第一个失败)、SimpleParallel(主任务+后台子树,主任务决定完成);UE 不提供通用 Parallel 节点;真正并行 N 分支需自定义 UBTCompositeNode 或串联多个 SimpleParallel。
  27. 配置 AI Perception:在 AIController 构造函数 include Perception/AISenseConfig_Sight.h、Perception/AISenseConfig_Hearing.h、Perception/AISenseConfig_Damage.h;创建 UAIPerceptionComponent,调用 SetPerceptionComponent(*AIP)。
  28. 配置 Sight:创建 UAISenseConfig_Sight;设置 SightRadius、LoseSightRadius、PeripheralVisionAngleDegrees、AutoSuccessRangeFromLastSeenLocation、DetectionByAffiliation.bDetectEnemies;调用 AIP->ConfigureSense(*Sight);调用 AIP->SetDominantSense(Sight->GetSenseImplementation())。
  29. 配置 Hearing:创建 UAISenseConfig_Hearing;设置 HearingRange、DetectionByAffiliation.bDetectEnemies、DetectionByAffiliation.bDetectNeutrals;调用 AIP->ConfigureSense(*Hearing)。
  30. 处理感知更新:OnTargetPerceptionUpdated(AActor* Actor, FAIStimulus Stimulus);成功感知时 SetValueAsObject(TEXT("TargetActor"), Actor) 和 SetValueAsVector(TEXT("LastKnownLocation"), Stimulus.StimulusLocation);失去目标时保留 LastKnownLocation 用于调查。
  31. 手动报告噪音:UAISense_Hearing::ReportNoiseEvent(GetWorld(), Location, Loudness, Instigator, MaxRange, Tag)。
  32. 手动报告伤害:UAISense_Damage::ReportDamageEvent(GetWorld(), DamagedActor, Instigator, Amount, EventLoc, HitLoc)。
  33. 让被感知 Actor 注册刺激源:添加 UAIPerceptionStimuliSourceComponent;设置 bAutoRegister = true;RegisterForSense(TSubclassOf<UAISense>(UAISense_Sight::StaticClass()));RegisterForSense(TSubclassOf<UAISense>(UAISense_Hearing::StaticClass()))。
  34. 查询感知状态:GetAIPerceptionComponent()->GetCurrentlyPerceivedActors(UAISense_Sight::StaticClass(), Visible);GetPerceivedHostileActors(Hostiles);HasActiveStimulus(*Target, UAISense::GetSenseID<UAISense_Sight>());ForgetActor(Target);ForgetAll()。
  35. 感知委托:OnTargetPerceptionUpdated 每个 actor 感知状态变化时触发;OnPerceptionUpdated 每帧批量触发,签名 void(const TArray<AActor*>& UpdatedActors);还有 OnTargetPerceptionForgotten、OnTargetPerceptionInfoUpdated。
  36. 额外感知配置:UAISenseConfig_Touch(物理接触时触发)、UAISense_Team(通过 IGenericTeamAgentInterface 在队友间传播敌人意识)、UAISense_Prediction(预测未来位置,调用 UAISense_Prediction::RequestPawnPredictionEvent)。
  37. 导航系统:include NavigationSystem.h;用 UNavigationSystemV1::GetCurrent(GetWorld()) 获取导航系统。
  38. 随机可达点:FNavLocation ResultLoc;NavSys->GetRandomReachablePointInRadius(Origin, Radius, ResultLoc)。
  39. 投影到 NavMesh:NavSys->ProjectPointToNavigation(WorldLoc, Projected, FVector(500, 500, 500))。
  40. 同步路径查询:FPathFindingQuery Query;设置 Query.StartLocation、Query.EndLocation;NavSys->FindPathSync(Query);成功时读取 Result.Path->GetPathPoints()。
  41. 异步路径查询:用 GetPawn()->GetNavAgentPropertiesRef() 获取 FNavAgentProperties;NavSys->FindPathAsync(NavAgent, Query, FNavPathQueryDelegate::CreateUObject(this, &AMyAI::OnPathFound))。
  42. 动态障碍:在 actor 上添加 UNavModifierComponent;Mod->AreaClass = UNavArea_Obstacle::StaticClass()。
  43. 自定义导航过滤器:创建 UMyNavFilter : UNavigationQueryFilter;调用 MoveToActor(Target, -1.f, true, true, true, UMyNavFilter::StaticClass())。
  44. 运行时重建 NavMesh:在程序化生成后调用 NavSys->Build()。
  45. 访问 RecastNavMesh:Cast<ARecastNavMesh>(NavSys->GetDefaultNavDataInstance());关注 AgentRadius、AgentHeight、AgentMaxStepHeight、AgentMaxSlope;必须存在 ANavMeshBoundsVolume,否则不生成 tiles;流送/开放世界使用 UNavigationInvokerComponent 放在 AI pawn 上。
  46. Off-mesh links:在关卡中使用 ANavLinkProxy,或实现 INavLinkCustomInterface 处理穿越回调。
  47. EQS:include EnvironmentQuery/EnvQueryManager.h;用 TObjectPtr<UEnvQuery> FindCoverQuery 声明查询。
  48. 运行 EQS:FEnvQueryRequest Request(FindCoverQuery, this);Request.Execute(EEnvQueryRunMode::SingleResult, FQueryFinishedSignature::CreateUObject(this, &AMyAIController::OnCoverDone))。
  49. 处理 EQS 结果:OnCoverDone(TSharedPtr<FEnvQueryResult> Result);若 Result.IsValid() && Result->IsSuccessful(),SetValueAsVector(TEXT("CoverLocation"), Result->GetItemAsLocation(0))。
  50. EQS 运行模式:SingleResult(最便宜)、RandomBest5Pct、RandomBest25Pct、AllMatching。
  51. BTTask_RunEQSQuery:设置 EQSRequest.QueryTemplate、BlackboardKey、RunMode;异步生命周期通过 FBTEnvQueryTaskMemory.RequestID 管理。
  52. 自定义 EQS context:继承 UEnvQueryContext;重写 ProvideContext(FEnvQueryInstance& QI, FEnvQueryContextData& CD);从 QI.Owner 转 Pawn 取 Controller,从 Blackboard 取 TargetActor;若有效用 UEnvQueryItemType_Actor::SetContextHelper(CD, Enemy);参考 references/eqs-reference.md 配置 generator 和 test。
  53. State Trees(UE 5.1+):用于更简单状态机、设计师友好工作流、Smart Object 集成;复杂反应式战斗和基于优先级的打断用 Behavior Trees。
  54. State Tree 使用:Build.cs 加 GameplayStateTreeModule;include Components/StateTreeComponent.h;使用 UStateTreeComponent;构造函数 CreateDefaultSubobject<UStateTreeComponent>(TEXT("StateTree"));BeginPlay 调用 StateTreeComp->StartLogic()。
  55. State Tree tasks 使用 FStateTreeTaskBase + FInstanceDataType;重写 EnterState、Tick、ExitState。State Tree evaluators(FStateTreeEvaluatorBase)跨所有活动状态持续运行,用于共享上下文数据(最近敌人、威胁等级),类似 BT services。
  56. Smart Objects:在世界 actor 上添加 USmartObjectComponent,设置 SmartObjectDefinition;Build.cs 加 SmartObjectsModule;include SmartObjectSubsystem.h。
  57. 通过 USmartObjectSubsystem 交互:USmartObjectSubsystem::GetCurrent(GetWorld());FSmartObjectRequestFilter Filter;FSmartObjectRequest Req(FBox(Origin, Origin).ExpandBy(500.f), Filter);SOS->FindSmartObject(Req);若 Res.IsValid(),SOS->MarkSlotAsClaimed(Res.SlotHandle, ESmartObjectClaimPriority::Normal);用完后 SOS->MarkSlotAsFree(Handle)。
  58. 避免常见错误:不要轮询,采用事件驱动;如果 BTDecorator_Blackboard observer abort 或 WaitForMessage 能达到同样效果,不要在 TickTask 中每帧检查。
  59. 避免 BT 过度复杂:扁平化不必要的嵌套;services 用 Interval >= 0.5s 周期性更新知识;用 BTDecorator_Cooldown 限制昂贵 EQS。
  60. 避免 NavMesh 缺口:始终放置 ANavMeshBoundsVolume;流送/程序化关卡生成后调用 NavSys->Build(),或在 AI pawn 上使用 UNavigationInvokerComponent。
  61. 处理服务器 vs 客户端:AAIController 仅存在于服务器;通过 Pawn 复制属性复制 AI 状态,不要通过 controller;BT Blackboard 不复制。
  62. 大世界:使用层次化 NavMesh(RecastNavMesh actor 设置);在 Project Settings > AI > EQS 中设置每帧最大并行查询数。
  63. 边缘情况:飞行/游泳设置 FNavAgentProperties::bCanFly/bCanSwim;分配匹配 SupportedAgents flags 的 UNavArea 子类;自定义 UNavArea 定义通行成本和区域 flags,每个移动域创建一个(如 UNavArea_Water,对地面 agent 高成本,对游泳者零成本);通过 NavModifierVolumes 或 NavMesh 生成设置应用。
  64. Dedicated server:Sight perception 使用碰撞 trace 而非渲染,可正常工作;非服务器代码用 HasAuthority() 保护。
  65. AI 与 GAS:BT tasks 请求激活 ability;abilities 管理自己的 latent 逻辑。
  66. 相关技能:ue-actor-component-architecture 用于 AI 组件设置;ue-gameplay-framework 用于 GameMode AI 生成、controller/pawn 关系;ue-cpp-foundations 用于 delegates、subsystems、UObject;ue-gameplay-abilities 用于 GAS + AI 集成。
  67. 参考文件:references/behavior-tree-patterns.md 包含 patrol、combat、flee、investigate、squad BT 模式;references/eqs-reference.md 包含空间查询的 generator 和 test 配置。

适用边界 · 注意事项