[C++/UE] UE5中AI開發的一點功能梳理(四) – 行為樹Service、Task類型節點說明及行為樹啟動Programming Notes, DevNotes / By LoneliNerd / 2024 年 3 月 30 日 2024 年 3 月 30 日 行為樹Service節點說明用於取代Parallel節點的方案,可以添加在Task節點或者Decorator節點上,並可以通過指定Interval和Random Deviation來控制調用的頻率右鍵節點 -> Add Service 內置ServiceDefault Focus 使AI Controller可以快速訪問到指定的Actor,而不用通過Blackboard Key獲取Run EQSQuery 執行EQS查詢,把查詢結果保存到Blackbboard Key中 自定義Service行為樹上方工具列 -> New ServiceService藍圖自帶4式8種Function可供重載。且帶AI後綴的才能拿到AI Controller,否則只能拿到ActorReceive Activation(AI):父節點激活時觸發Receive Search Start(AI):自身所在節點激活時觸發Receive Tick(AI):節點執行中每幀觸發Receive Deactivation(AI):父節點結束時觸發 行為樹Task節點說明行為樹具體要執行的行為右鍵節點 -> Add Task 內置TaskFinish With Result:直接返回某個結果(Succeeded/Failed/Aborted/InProgress)Make Noise:如果Pawn上有PawnNoiseEmitter,該Task就會對實現了AIHearing監聽的對象發送消息,通知他們「聽到了」Pawn發出的Noise //BTTask_MakeNoise.cpp EBTNodeResult::Type UBTTask_MakeNoise::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) { const AController* MyController = Cast<AController>(OwnerComp.GetOwner()); APawn* MyPawn = MyController ? MyController->GetPawn() : NULL; if (MyPawn) { MyPawn->MakeNoise(Loudnes, MyPawn); return EBTNodeResult::Succeeded; } return EBTNodeResult::Failed; } //Actor.cpp void AActor::MakeNoise(float Loudness, APawn* NoiseInstigator, FVector NoiseLocation, float MaxRange, FName Tag) { NoiseInstigator = NoiseInstigator ? NoiseInstigator : GetInstigator(); if ((GetNetMode() != NM_Client) && NoiseInstigator) { AActor::MakeNoiseDelegate.Execute(this, Loudness, NoiseInstigator , NoiseLocation.IsZero() ? GetActorLocation() : NoiseLocation , MaxRange , Tag); } } void AActor::SetMakeNoiseDelegate(const FMakeNoiseDelegate& NewDelegate) { if (NewDelegate.IsBound()) { MakeNoiseDelegate = NewDelegate; } } //AISense_Hearing.cpp void UAISense_Hearing::RegisterMakeNoiseDelegate() { AActor::SetMakeNoiseDelegate(FMakeNoiseDelegate::CreateStatic(&UAIPerceptionSystem::MakeNoiseImpl)); } Move Directly Toward / Move ToMove Directly Toward:不使用導航系統,使Actor直線移動到目標(位置)Move To:使用導航系統,使Actor移動到目標(位置)主要參數:Acceptable Radius:距離目標於該半徑內時節點返回SucceeedReach Test Includes Agent Radius AI角色的Capsule半徑是否要加入計算考慮Reach Test Includes Goal Radius 終點的Capsule半徑是否要加入計算考慮Allow Strafe:移動期間是否要注視著目標Allow Partial Path 如果目標無法到達,也會走一條不完整的路線Track Moving Goal 會追蹤一直移動的目標Require Navigable End Location 需保證終點是可被導航達到的Observe Blackboard Value 如果目標的Blackboard Key改變了,追蹤的目標也會改變 //PathFollowingComponent.cpp FVector UPathFollowingComponent::GetMoveFocus(bool bAllowStrafe) const { FVector MoveFocus = FVector::ZeroVector; if (bAllowStrafe && DestinationActor.IsValid()) { MoveFocus = DestinationActor->GetActorLocation(); } else { const FVector CurrentMoveDirection = GetCurrentDirection(); MoveFocus = *CurrentDestination + (CurrentMoveDirection * FAIConfig::Navigation::FocalPointDistance); } return MoveFocus; } Play Animation:播放動畫Play Sound:播放聲音Rotate to Face BBEntry:旋轉面向某Blackboard Actor KeyRun Behavior:執行子樹(運行時不可變)Run Behavior Dynamic:執行子樹(運行時可調用SetDynamicSubtree設置子樹資源)Inject Tag:SetDynamicSubtree時用來查找具體要修改哪一個Run Behavior Dynamic任務節點的子樹資源的Run EQSQuery:執行EQS查詢,把查詢結果保存到Blackbboard Key中Set Tag Cooldown:配合Tag Cooldown Decorator使用,防止行為樹執行Wait:等待Wait Blackboard Time:等待Blackboard上某個float值 自定義Task行為樹上方工具列 -> New TaskTask藍圖自帶3式6種Function可供重載。且帶AI後綴的才能拿到AI Controller,否則只能拿到ActorReceive Execute:節點開始執行時觸發執行完畢需要分別調用FinishExecute(Success = true),和FinishExecute(Success = false),否則節點執行會堵塞Receive Tick:節點執行中每幀觸發Receive Abort:節點結束/打斷時觸發執行完畢需要分別調用FinishAbort(Success = true),和FinishAbort(Success = false),否則節點執行會堵塞 行為樹啟動及運行在AI角色的AI Controller藍圖中,在適當的時機(如Event Begin Play)裡直接啟動對應的行為樹即可 => Run Behavior Tree, BTAsset = 行為樹資源不過需要注意AI角色配置中的Auto Possess AI不能Disabled,否則就要如上文寫的,需要手動Possess後再啟動 執行順序為由上至下,由左往右