0. 개요

비헤이비어 트리에서 각 노드의 연결을 통해 AI의 작동 양식을 설정할 수 있다.

노드는 크게 시퀀스 노드와 태스크 노드로 구분된다.

 

(1) 시퀀스 노드

- 시퀀스 노드는 여러 노드를 왼쪽에서 오른쪽으로 순차적으로 실행한다.

- 하위 노드 중 하나가 실패할 때까지 실행한다.

 

(2) 태스크 노드

- AI가 수행하는 동작을 정의한다.

- 움직임, 노이즈 발생 등

 

(3) 데코레이터

- 노드에 조건을 부여함.

- 어떤 상태에 대한 조건을 부여하여 하위 노드의 실행을 관리한다.

 

블랙보드 데코레이터를 사용하여 블랙보드의 키를 관찰하여 성공, 실패 여부를 판정할 수 있다.

아래 코드에서는 하위 노드인 Clear Blackboard Value를 생성하여 Has Investigated? 시퀀스가 실패하게 만든다.

 

(4) 흐름

(4-1) AI 컨트롤러

- AI 컨트롤러가 매 틱마다 플레이어의 위치를 찾는다.

- LineOfSightTo 함수를 사용하여 시야 내에 플레이어가 있는지 체크한다.

- 플레이어가 발견되면 PlayerLocation과 LastKnownPlayerLocation에 해당 위치를 기록한다.

- 플레이어가 발견되지 않으면 PlayerLocation을 초기화한다.

 

(4-2) 비헤이비어 트리

- 플레이어가 시야에서 벗어나면 Move To PlayerLocation이 들어있는 Can See Player? 시퀀스가 실패한다.

- LastKnownPlayerLocation으로 이동한다.

- 이어서 LastKnownPlayerLocation 값이 제거된다.

- 5초 기다린 후 해당 시퀀스가 다시 발동되고 실패를 반환한다.

- 두 개의 시퀀스가 실패이므로 StartLocation으로 돌아간다.

 

 

1. 사전 작업

블랙보드의 시퀀스 노드 코드를 작성하기 앞서, SimpleShooter.Build.cs에 아래 내용을 수정한다.

GameplayTasks 모듈을 추가하지 않으면 제대로 컴파일되지 않는다.

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "GameplayTasks" });

 

 

2. 비헤이비어 트리 노드 생성

(1) C++ 클래스 생성

모든 클래스 탭에서 BTTask를 검색 후 BTTask_BlackboardBase를 상속받는다.

BTTaskNode를 상속받아도 되지만, BlackboardBase를 상속받으면 블랙보드 키를 디테일 창에서 수정할 수 있게 된다.

 

 

(2) 노드 이름 설정

UBTTask_ClearBlackboardValue::UBTTask_ClearBlackboardValue()
{
    NodeName = TEXT("Clear Blackboard Value");
}

노드의 생성자를 만들고 TEXT 매크로를 이용하여 노드의 이름을 지어준다.

 

 

(3) ClearBlackboardNode 구현

#include "BehaviorTree/BlackboardComponent.h"
EBTNodeResult::Type UBTTask_ClearBlackboardValue::ExecuteTask(UBehaviorTreeComponent &OwnerComp, uint8 *NodeMemory)
{
    Super::ExecuteTask(OwnerComp, NodeMemory);

    OwnerComp.GetBlackboardComponent()->ClearValue(GetSelectedBlackboardKey());

    return EBTNodeResult::Succeeded; // Failed, Aborted, InProgress(여러 틱 호출 시 사용)
}

부모에게서 상속받은 함수 중 하나인 ExecuteTask를 상속받아서 기능을 구현한다.

이 노드는 선택된 키의 값을 제거한다.

리턴 값으로 EBTNodeResult 열거형 중 하나를 리턴한다.

- Succeeded : 성공, 기능 실행 후 성공을 반환함.

- Failed : 실패, 기능 실행 후 실패를 반환함.

- Aborted : 취소됨, 실패와 유사하게 작동함.

- InProgress : 작동 중, 매 틱마다 해당 노드의 기능을 사용할 필요가 있을 때 사용한다.