[언리얼엔진] Behavior Tree 인스턴스

2025. 5. 28. 21:22·언리얼 엔진/트러블슈팅

1. 개요

하나의 Behavior Tree로 다수의 AI를 구현하고자 했다. 당연히 Behavior Tree가 각각 인스턴스화 돼서 작동하겠거니 했지만, "A"가 도망 상태로 전이될 때 전혀 관계없는 "B"도 도망 상태로 전이되는 것을 보고 의아했다. Task 노드에 상태 변수 값을 로그로 출력해본 결과, 동시에 같은 로그 값이 찍히는 것을 확인했다. Behavior Tree가 인스턴스화 되는 것이 아닌 공유로써 사용이 될 것이라 가정을 했다.

 


 

2. 원인

언리얼엔진 공식문서

정말이지 .. 비헤이비어 트리는 물론 노드까지 공유한다고 명시되어 있다.

 


 

3-1. 해결 방법 ( bCreateNodeInstance = true )

UBTTask_EnhancedIdle::UBTTask_EnhancedIdle()
{
	NodeName = "Enhanced Idle";
	bNotifyTick = true;
	bCreateNodeInstance = true;
}

첫 번째 해결방법으로 노드의 생성자에서 Instance 상태 값을 활성화 하는 것이다. 이 방법은 기존에 구현한 Task 노드를 있는 그대로 사용할 수 있지만 노드가 AI 수만큼 인스턴스화 되다 보니 메모리를 많이 차지한다는 단점이 존재한다.

언리얼엔진 공식문서에도 나와있듯, **일정량의 퍼포먼스를 희생한다**라고 명시되어있다.

 

3-2. 해결 방법 ( NodeMemory )

두 번째 해결방법은 메모리를 효율적으로 관리할 수는 있으나 구현이 살짝 까다롭다는 단점이 있다. 하지만, 메모리 최적화 능력은 필수적인 소양이기에 적극적으로 해당 방법을 활용을 해야 한다고 볼 수 있다.

 

UBTTask_EnhancedIdle.h

struct FBTIdleTaskMemory
{
	/** 빙의한 AIController에 대한 참조 */
	TWeakObjectPtr<AEnhancedBossAIController> AIController;

	/** AIController의 주체에 대한 참조 */
	TWeakObjectPtr<ABoss> Boss;
	
	/** 현재까지 경과된 시간 */
	float AccumulatedTime;

	/** Idle 작업이 끝나는 시간 */
	float IdleFinishTime;
};

UCLASS()
class ABYSSDIVERUNDERWORLD_API UBTTask_EnhancedIdle : public UBTTask_BlackboardBase
{
	GENERATED_BODY()
    
public:
	/** NodeMemory의 크기를 반환하는 함수
	* 구현하지 않으면 NodeMemory 크기를 실제 크기보다 작거나 큰 크기로 반환하기 때문에
	* NodeMemory를 참조하는 과정에서 잘못된 주소를 참조할 수 있다. **/
	virtual uint16 GetInstanceMemorySize() const override { return sizeof(FBTIdleTaskMemory); }
}

UBTTask_EnhancedIdle.cpp

EBTNodeResult::Type UBTTask_EnhancedIdle::ExecuteTask(UBehaviorTreeComponent& Comp, uint8* NodeMemory)
{
	FBTIdleTaskMemory* TaskMemory = (FBTIdleTaskMemory*)NodeMemory;
	if (!TaskMemory) return EBTNodeResult::Failed;

	TaskMemory->AIController = Cast<AEnhancedBossAIController>(Comp.GetAIOwner());
	if (!TaskMemory->AIController.IsValid()) return EBTNodeResult::Failed;

	TaskMemory->Boss = Cast<ABoss>(TaskMemory->AIController->GetPawn());
	if (!TaskMemory->Boss.IsValid()) return EBTNodeResult::Failed;
	
	TaskMemory->Boss->SetBossState(EBossState::Idle);
	TaskMemory->AccumulatedTime = 0.f;
	TaskMemory->IdleFinishTime = FMath::RandRange(IdleFinishMinInterval, IdleFinishMaxInterval);
	
	return EBTNodeResult::InProgress;
}

변수에 접근을 해야할 때마다 NodeMemory를 참조하여 접근해야 한다는 번거로움이 있지만, 메모리 측면에서 효율적이기 때문에 권장되는 방법이다. 추가로 알아둬야 할 점은 NodeMemory로 사용할 구조체의 멤버변수는 Garbage Collector가 관리해주지 않기 때문에 TWeakObjectPtr 을 사용해야 한다는 것이다.

'언리얼 엔진 > 트러블슈팅' 카테고리의 다른 글

[언리얼엔진] C++ 파일 경로 문제  (0) 2025.06.18
[언리얼엔진] 3D NavMesh (Flying Navigation System)  (1) 2025.06.05
[언리얼엔진] ApplyPointDamage  (0) 2025.05.20
[언리얼엔진] Simulate Physics + Physics Asset  (0) 2025.05.20
[언리얼엔진] 렌더링 최적화 팁  (0) 2025.05.20
'언리얼 엔진/트러블슈팅' 카테고리의 다른 글
  • [언리얼엔진] C++ 파일 경로 문제
  • [언리얼엔진] 3D NavMesh (Flying Navigation System)
  • [언리얼엔진] ApplyPointDamage
  • [언리얼엔진] Simulate Physics + Physics Asset
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (229)
      • 게임잼 (3)
      • 언리얼 엔진 (53)
        • 꿀 Tip ! (7)
        • 트러블슈팅 (24)
        • 최적화 (0)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • 문자열 (0)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 프로젝트 (25)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • GetOutOf (15)
      • 기타 (54)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (10)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    삽입정렬
    게임잼
    셸정렬
    게임개발
    선택정렬
    버블정렬
    경북게임잼
    알고리즘
    자료구조
    참가후기
    쉘정렬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[언리얼엔진] Behavior Tree 인스턴스
상단으로

티스토리툴바