C++/Unreal Engine

[UE4] Behavior Tree 정리

로파이 2021. 10. 15. 18:57

관련 모듈 : 블랙보드, 비헤이비어 트리 : "AIModule", 네비게이션 "NavigationSystem", 태스크 클래스 : "GameplayTasks"

 

Character(Pawn)에서 생성시 사용되는 컨트롤러를 지정

AIControllerClass = ASimpleAIController::StaticClass();
AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned;

 

AIController의 OnPossess(APawn* InPawn) 혹은 BeginPlay() 에서 BT 에셋과 BB 에셋을 등록

1) AIController의 멤버 BlackboardComponent와 블랙보드 에셋을 바인딩

bool AAIController::UseBlackboard(UBlackboardData* BlackboardAsset, UBlackboardComponent*& BlackboardComponent)

2) BehaviorTree 에셋을 시동

bool AAIController::RunBehaviorTree(UBehaviorTree* BTAsset)

 

Blackboard의 데이터 사용

UseBlackboard의 성공적인 등록 이후 UBlackboardComponent의 SetValueAsXXX 혹은 GetValueAsXXX를 사용한다.

// Get
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
FVector GetValueAsVector(const FName& KeyName) const;
    
// Set
UFUNCTION(BlueprintCallable, Category="AI|Components|Blackboard")
void SetValueAsVector(const FName& KeyName, FVector VectorValue);

 

UBTTaskNode

ExecuteTask는 EBTNodeResult(Failed, Succeeded, InProgress)를 반환해야한다.

virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)

Abort관련 함수도 있다. (Aborted, InProgress) 둘 중 하나를 반환해야한다.

virtual EBTNodeResult::Type AbortTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory);

- TickTask는 서비스 노드용이기 때문에 호출되지 않으므로 사용하지 않는다.

 

기초 활용 (ExecuteTask 내에서)

도달가능한 랜덤 포인트 지점 찾기

"NavigationSystem.h"의 UNavigationSystemV1을 이용

bool GetRandomReachablePointInRadius
(
    const FVector & Origin,
    float Radius,
    FNavLocation & ResultLocation,
    ANavigationData * NavData,
    FSharedConstNavQueryFilter QueryFilter
) const
 UNavigationSystemV1* NavSystem = UNavigationSystemV1::GetNavigationSystem(Pawn->GetWorld());
 if (NavSystem == nullptr)
 	return EBTNodeResult::Failed;

FVector Origin = OwnerComp.GetBlackboardComponent()->GetValueAsVector(ASimpleAIController::CenterPosKey);

FNavLocation NextPatrol;
if (NavSystem->GetRandomReachablePointInRadius(Origin, Radius, NextPatrol))
{
	OwnerComp.GetBlackboardComponent()->SetValueAsVector(ASimpleAIController::PatrolPosKey, NextPatrol.Location);
	return EBTNodeResult::Succeeded;
}

 

UBTService

컴포짓이나 태스크 노드에 부착되어 해당 분기가 동작 중이면 정해진 주기에 따라 서비스 노드를 실행한다. 서비스 노드는 주로 확인을 하거나 블랙보드를 업데이트하는데 사용한다. 다른 일반적인 행동트리 시스템에서 전통적으로 행해지던 병렬 노드 (Parallel Node)를 대체하는 것.

 

  • float Interval(멤버 변수) : TickNode 콜의 주기를 결정한다.
  • TickNode
virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds);

 

 

 

 

참고자료

Setting Up Advanced AI : https://www.youtube.com/watch?v=NZZtMNdJk5o