언리얼 엔진
Unreal AI - AIController 헤더 구성과 멤버 선언 이유
로안님
2025. 4. 4. 17:36
AI 컨트롤러 헤더 구성과 컨벤션 설명
언리얼 엔진에서 AI를 C++로 설계할 때, AIController의 헤더에 어떤 멤버를 어떻게 선언하느냐는 설계의 명확성, 블루프린트와의 연결성, 유지보수성에 큰 영향을 미친다. 이 글에서는 다음 세 가지 멤버 변수에 대해 설명한다:
UPROPERTY(EditDefaultsOnly, Category = "AI")
UBlackboardData* BlackboardAsset;
UPROPERTY(EditDefaultsOnly, Category = "AI")
UBehaviorTree* BehaviorTreeAsset;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "AI", meta = (AllowPrivateAccess = "true"))
UBlackboardComponent* BlackboardComponent;
1. 왜 이 멤버들을 AIController 헤더에 선언하는가?
AIController는 AI의 의사결정 시스템의 시작점이며, 여기서 블랙보드와 비헤이비어 트리를 로드 및 실행한다. 따라서 다음과 같은 멤버들이 필요하다:
변수 설명
BlackboardAsset | 블랙보드 데이터(.uasset). 어떤 키들이 존재하는지 정의한다. |
BehaviorTreeAsset | 실행할 비헤이비어 트리(.uasset). AI의 로직 순서를 담고 있다. |
BlackboardComponent | 런타임 중 실제 블랙보드 데이터를 읽고 쓰는 컴포넌트. |
이 세 변수는 모두 AI의 초기화와 실행 흐름에 필수적이기 때문에 AIController 클래스의 멤버로 선언하는 것이 자연스럽다.
2. 접근 제어자: 왜 어떤 건 protected이고 어떤 건 private인가?
BlackboardAsset, BehaviorTreeAsset → protected
- 에디터에서 세팅되는 자산(.uasset)이고, 런타임에 변경되지 않음
- 외부에서 직접 접근할 필요는 없지만, 자식 클래스에서 접근할 가능성이 있음
- 따라서 protected로 선언하여 내부 접근은 가능하게 유지
BlackboardComponent → private
- 런타임에 내부적으로만 접근하고, 외부에서 직접 변경하면 위험함
- 하지만 블루프린트에서 확인(읽기)할 필요는 있기 때문에
- BlueprintReadOnly + AllowPrivateAccess = true 로 블루프 전용 읽기만 허용
3. 왜 BlackboardComponent만 AllowPrivateAccess = true를 쓰는가?
언리얼의 UPROPERTY() 시스템에서는 BlueprintReadOnly만으로는 private 변수에 접근이 불가능하다. 그래서 블루프린트에서 해당 값을 읽을 수 있게 하려면 다음 조건이 필요하다:
- BlueprintReadOnly
- meta = (AllowPrivateAccess = "true")
BlackboardComponent는 실행 중 AI가 어떤 타겟을 보고 있는지, 어떤 조건이 참인지 확인하기 위해 블루프린트에서 자주 읽는 변수다. 반면 BehaviorTreeAsset, BlackboardAsset은 에디터에서만 설정하고, 런타임에는 바뀌지 않기 때문에 블루프린트에서 읽을 일이 거의 없다.
따라서 BlackboardComponent에만 AllowPrivateAccess를 붙이는 것이 실용적이다.
결론
- AIController는 블랙보드와 비헤이비어 트리를 실행하는 중심 클래스이므로 관련 멤버를 반드시 포함해야 한다.
- 자산은 protected, 런타임 컴포넌트는 private + 블루프 전용 접근 허용 방식이 깔끔하고 안정적인 설계다.
- 블루프린트에서 실제 디버깅에 쓰이는 요소만 AllowPrivateAccess로 노출하는 것이 유지보수에 유리하다.