비헤이비어 트리 노드 레퍼런스

비헤이비어 트리 에디터에서 작업할 때 사용할 수 있는 다양한 타입의 노드에 대해 간략하게 살펴봅니다.

Choose your operating system:

Windows

macOS

Linux

비헤이비어 트리 노드(Behavior Tree Node)(base classUBTNode)는 태스크, 로직 흐름 제어, 데이터 업데이트 등 비헤이비어 트리의 주요 작업을 수행합니다.

비헤이비어 트리 노드 타입

비헤이비어 트리의 시작점 역할을 하는 노드는 루트(Root) 노드 입니다. 루트 노드는 해당 트리의 고유한 노드이며, 몇 가지 특별한 규칙을 갖습니다. 하나의 연결만 가질 수 있고, 데코레이터(Decorator) 노드 또는 서비스(Service) 노드 어태치를 지원하지 않는다는 것입니다. 루트 노드는 자체 프로퍼티를 갖지 않지만, 이 노드를 선택하면 디테일(Details) 패널에 비헤이비어 트리 의 프로퍼티가 표시되며, 여기서 비헤이비어 트리의 블랙보드 에셋(Blackboard Asset) 을 설정할 수 있습니다.

루트 노드는 자체 프로퍼티를 갖지 않지만 이 노드를 선택하면 디테일 패널에 비헤이비어 트리의 프로퍼티가 표시되며, 여기서 비헤이비어 트리의 블랙보드 에셋을 설정할 수 있습니다.

비헤이비어 트리 노드에는 루트 노드 외에도 다음과 같은 네 가지 타입이 있습니다.

노드 타입

설명

컴포짓 노드(Composite Nodes)

이 노드는 분기의 루트와 해당 분기가 실행되는 방식의 기본 규칙을 정의합니다.

태스크 노드(Task Nodes)

이 노드는 비헤이비어 트리의 리프입니다. 실행할 수 있는 액션을 나타내며, 출력 연결을 갖지 않습니다.

데코레이터 노드(Decorator Nodes)

조건식이라고도 합니다. 이 노드는 다른 노드에 어태치되어 트리의 분기나 단일 노드의 실행 여부를 결정합니다.

서비스 노드(Service Nodes)

이 노드는 컴포짓 노드에 어태치되며, 자신의 분기가 실행되는 동안에 한해 정의된 주기로 실행됩니다. 보통 블랙보드의 확인 및 업데이트에 사용됩니다. 이 노드는 다른 비헤이비어 트리 시스템에서의 전통적인 병렬(Parallel) 노드를 대체합니다.

비헤이비어 트리 노드 인스턴싱 정책

비헤이비어 트리 노드(이하 '노드')는 공유 오브젝트로 존재하며, 이는 동일한 비헤이비어 트리를 사용하는 에이전트는 모두 단일한 노드 인스턴스 세트를 공유한다는 것을 의미합니다. 따라서 메모리 사용을 줄이면서 CPU 퍼포먼스를 개선할 뿐 아니라, 노드가 에이전트별 데이터를 저장하지 않도록 방지합니다. 하지만 에이전트가 노드와 관련된 정보를 저장 및 업데이트해야 하는 경우, 언리얼 엔진에서는 세 가지 솔루션을 제공합니다.

노드 인스턴싱

노드의 bCreateNodeInstance 변수가 true 로 설정된 경우, 비헤이비어 트리를 사용하는 각 에이전트에 노드의 고유 인스턴스를 제공함으로써 일정량의 퍼포먼스를 희생하고 메모리를 사용하여 에이전트별 데이터를 안전하게 저장할 수 있습니다. UBTTask_BlueprintBase , UBTTask_PlayAnimation , UBTTask_RunBehaviorDynamic 등 특정 언리얼 엔진 노드 클래스가 이 기능을 사용합니다.

블랙보드에 저장

일반적인 솔루션 중 하나는 변수를 블랙보드에 저장하는 것입니다. 그러려면 노드에서 변수 이름을 노출하고, 노드를 초기화하는 동안 해당 이름으로 블랙보드 키를 가져와서 저장하면 됩니다. 그런 다음 해당 블랙보드 키를 사용하여 변수의 값을 구하고 에이전트의 블랙보드 인스턴스에 설정하면 됩니다. 이 메서드는 bool , float , FVector , int32 , enum (uint8 로 저장됨), UObject* 타입의 변수를 지원합니다.

비헤이비어 트리 노드에 저장

커스텀 구조체 또는 클래스를 생성하여 노드의 메모리에 변수를 저장할 수 있습니다. 예를 들면 UBTTask_MoteTo 클래스는 FBTMoveToTaskMemory 를 사용합니다. BTTask_MoteTo.h 에서 다음과 같은 코드를 찾을 수 있습니다.

struct FBTMoveToTaskMemory
{
    /** 이동 요청 ID */
    FAIRequestID MoveRequestID;

    FDelegateHandle BBObserverDelegateHandle;
    FVector PreviousGoalLocation;

    TWeakObjectPtr<UAITask_MoveTo> Task;

    uint8 bWaitingForPath : 1;
    uint8 bObserverCanFinishTask : 1;
};

UBTNode 의 많은 가상 함수는 노드의 메모리에 uint8* 파라미터를 취합니다. 이 파라미터는 에이전트에 할당된 메모리 블록, 즉 GetInstanceMemorySize 의 오버라이드된 버전으로 반환되는 크기를 나타냅니다. 노드는 이 메모리 용량을 각 에이전트에 할당하며, 이 메모리를 단일 인접 블록에 저장하여 퍼포먼스를 최적화합니다. 하지만 이 메모리는 UObject 생태계의 일부가 아니고 언리얼 엔진 리플렉션 시스템의 일부도 아니기 때문에 가비지 컬렉션(Garbage Collection)에 표시되지 않습니다. 따라서 UPROPERTY 지원을 사용할 수 없으며 TWeakObjectPtr 를 통해 UObject 포인터를 저장하는 것이 권장됩니다.