안동민 개발노트

본문 시작

AI와 행동 트리

AI Controller와 Navigation Mesh를 준비하고 Blackboard·Task·Decorator로 NPC 행동 트리를 설계합니다.

이전 절에서는 언리얼 에디터 확장과 커스텀 툴 개발을 다뤘습니다.

이번 절에서는 언리얼 엔진에서 자주 사용하는 인공지능(AI) 구조, 특히 행동 트리(Behavior Tree)의 구성과 디버깅 방법을 살펴봅니다.

이번 절에서는 언리얼 엔진의 AI 시스템 기본 개념부터 시작하여, 행동 트리의 구조와 작동 방식, 그리고 효과적인 행동 트리 설계를 위한 모범 사례까지 자세히 살펴보겠습니다.


게임 AI의 기본 개념

게임 AI는 플레이어의 행동에 반응하고, 게임 세계 내에서 지능적인 것처럼 보이는 결정을 내리도록 설계된 비플레이어 캐릭터(NPC)의 동작을 제어하는 시스템을 의미합니다.

  • NPC (Non-Player Character): 플레이어가 아닌 캐릭터로, AI에 의해 제어됩니다.
  • 지능: 게임 AI에서 지능은 실제 인간의 지능과는 다르며, 미리 정의된 규칙, 알고리즘, 데이터에 기반하여 목표를 달성하는 능력을 의미합니다.
  • 의사 결정: AI는 환경 분석, 목표 설정, 행동 계획 수립 등의 과정을 통해 의사 결정을 내립니다.

언리얼 엔진은 AI를 구현하기 위한 다양한 내장 기능을 제공하며, 그 중심에는 AI 컨트롤러(AI Controller)와 행동 트리(Behavior Tree), 그리고 블랙보드(Blackboard)가 있습니다.


AI 컨트롤러 (AI Controller)

이 절의 Pawn 기반 AI는 자신을 소유하는 AI Controller가 행동을 제어합니다. 모든 AI 구현에 Controller가 필수인 것은 아닙니다.

AI 컨트롤러는 플레이어의 PlayerController와 유사하게, 해당 캐릭터의 인지(Perception), 의사 결정(Decision Making), 행동(Action Execution) 로직을 담당합니다.

  • 설정: Character 블루프린트나 C++ 클래스에서 AI Controller Class 속성을 설정하여 해당 캐릭터가 사용할 AI 컨트롤러를 지정합니다. 배치/생성 방식에 맞는 Auto Possess AI를 설정하고 소유가 완료된 시점에 Behavior Tree를 실행합니다.
  • 주요 기능
    • Perception (인지): AIPerceptionComponent를 사용하여 시각(Sight), 청각(Hearing), 피해 감지(Damage) 등 다양한 방식으로 게임 세계를 인지합니다.
    • Movement (이동): MoveToActor 또는 MoveToLocation 함수를 사용하여 내비게이션 시스템(Navigation Mesh)을 통해 캐릭터를 이동시킵니다.
    • Behavior (행동): 행동 트리를 실행하여 캐릭터의 복잡한 행동을 제어합니다.

내비게이션 메시 (Navigation Mesh)

AI 캐릭터가 게임 월드 내에서 이동할 수 있는 영역을 정의하는 시스템입니다.

언리얼 엔진은 Nav Mesh Bounds Volume을 사용하여 내비게이션 메시를 자동으로 생성합니다.

  • 작동 방식: 에디터에서 P 키를 누르면 내비게이션 메시(기본적으로 녹색)가 시각화됩니다. NavMesh 기반 지상 이동은 생성된 내비게이션 데이터와 연결 영역을 사용합니다. 비행·직접 이동 등 다른 이동 방식까지 NavMesh로 제한되는 것은 아닙니다.
  • 활용: AI가 복잡한 환경에서 장애물을 회피하며 목표 지점까지 도달할 수 있도록 해줍니다.

행동 트리 (Behavior Tree)

행동 트리는 AI의 의사 결정을 계층적이고 유연하게 구성하는 데 사용되는 트리(Tree) 구조의 시스템입니다.

특히 복잡한 AI 행동을 시각적으로 설계하고 디버깅하기에 매우 효과적입니다.

행동 트리의 핵심 구성 요소

  • Root (루트): 행동 트리의 시작점. 항상 하나만 존재합니다.
  • Composites (복합 노드): 자식 노드들의 실행 흐름을 제어합니다.
    • Selector (선택자): 자식 노드를 왼쪽에서 오른쪽으로 순서대로 시도하며, 자식이 성공할 때까지 시도합니다. 자식이 InProgress이면 그 실행을 기다리며 즉시 다음 자식으로 넘어가지 않습니다. 하나라도 성공하면 자신도 성공하고, 모든 자식이 실패하면 자신도 실패합니다. (예: 싸울 수 있다면 싸우고, 아니면 도망쳐라)
    • Sequence (시퀀스): 자식 노드를 왼쪽에서 오른쪽으로 순서대로 실행하며, 모든 자식이 성공해야 자신도 성공합니다. 하나라도 실패하면 자신도 실패합니다. (예: 목표를 찾고, 경로를 계산하고, 이동한 다음, 공격해라)
    • Simple Parallel (단순 병렬): 하나의 Main Task와 보조 서브트리를 함께 진행합니다. 완료 모드에 따라 보조 작업의 종료를 처리하며 CPU 멀티스레드 실행을 뜻하지 않습니다.
  • Decorators (데코레이터 / 조건부 노드): 자식 노드의 실행 여부를 결정하는 조건부 로직을 추가합니다.
    • Blackboard-based Decorator: 블랙보드 값을 기반으로 조건을 검사합니다.
    • 거리 조건: 제공되는 거리 검사나 커스텀 데코레이터로 플레이어와의 거리를 비교합니다. Is Player Closer를 공통 내장 노드 이름으로 가정하지 않습니다.
    • Cooldown: 특정 행동의 재사용 대기시간을 설정합니다.
    • Force Success: 결과를 성공으로 바꾸는 데코레이터입니다. 실패 경로를 숨기지 않도록 목적을 명확히 합니다.
  • Services (서비스): 연결된 브랜치가 활성화된 동안 지정한 주기마다 실행되어, 블랙보드 값을 업데이트하거나 환경을 모니터링하는 데 사용됩니다.
    • Tick Interval을 설정하여 서비스가 실행될 간격을 제어합니다. (예: 0.5초마다 플레이어 위치를 확인하여 블랙보드에 기록)
  • Tasks (작업 노드): AI가 실제로 수행하는 가장 작은 단위의 행동입니다.
    • Move To: 특정 위치나 액터로 이동합니다.
    • Wait: 일정 시간 동안 대기합니다.
    • Play Animation: 애니메이션을 재생합니다.
    • Run EQS: 환경 쿼리 시스템(EQS)을 실행하여 최적의 위치를 찾습니다.
    • Custom Task (사용자 정의 작업): 블루프린트나 C++로 직접 커스텀 작업을 구현할 수 있습니다. (예: 총 발사, 스킬 사용)

블랙보드 (Blackboard)

블랙보드는 행동 트리와 함께 사용되는 AI 데이터 저장소입니다.

AI 컨트롤러가 게임 세계에서 인지하거나 계산한 중요한 정보(예: 플레이어 위치, 목표 액터, 경계 상태)를 저장하고, 행동 트리의 각 노드가 이 정보에 접근하여 의사 결정을 내리는 데 사용됩니다.

  • 키-값 쌍: UBlackboardData 에셋으로 정의되며, 이름(FName)으로 식별하는 키와 특정 타입(Vector, Object, Bool 등)의 값으로 구성됩니다.
  • 액세스: 행동 트리 내의 데코레이터, 서비스, 작업 노드는 모두 블랙보드 키를 참조하여 값을 읽거나 쓸 수 있습니다.
  • 장점: AI 로직과 데이터 관리 부분을 분리하여 재사용성과 가독성을 높입니다.

행동 트리 설계 및 구현 모범 사례

계층적 설계

  • 모듈성: 거대한 단일 행동 트리보다는, 작은 행동 트리들을 만들고 Run Behavior 작업을 통해 다른 행동 트리를 서브 트리(Subtree)처럼 호출하도록 합니다. 이는 재사용성을 높이고 관리하기 쉽게 만듭니다.
  • 추상화: 상위 레벨의 노드는 목표를 달성하라와 같은 추상적인 행동을 정의하고, 하위 레벨 노드에서 이를 구체적인 작업으로 분해합니다.

블랙보드 활용

  • 중앙 집중식 데이터: 행동 판단에 필요한 키를 Blackboard에 두고, 원본 게임 상태나 큰 데이터 전체를 중복 복사하지 않습니다. 키별 갱신 주체를 정합니다.
  • 명확한 키 정의: 블랙보드 키의 이름을 명확하게 정의하여 어떤 정보를 저장하는지 쉽게 알 수 있도록 합니다.
  • 데이터 타입 일치: 키에 저장되는 데이터 타입이 일치하도록 주의합니다.

데코레이터의 현명한 사용

  • 조건부 실행: 데코레이터는 불필요한 행동 트리의 순회를 막아 성능을 향상시키고 로직을 명확하게 합니다.
  • 재평가(Observer Aborts): 데코레이터의 Observer Aborts 설정을 통해 조건이 변경될 때 현재 실행 중인 행동 트리 브랜치를 중단하고 재평가할지 결정합니다. 이는 AI의 반응성을 높이는 데 중요합니다.
    • None: 조건이 변경되어도 현재 브랜치 중단 안함.
    • Self: 조건이 더 이상 맞지 않으면 자신이 붙은 브랜치의 진행을 중단합니다.
    • Lower Priority: 자신보다 낮은 우선순위(오른쪽) 브랜치를 중단해 높은 우선순위로 전환할 수 있게 합니다.
    • Both: Self와 Lower Priority의 중단 범위를 함께 사용합니다. 관찰하는 값과 Notify Observer 조건도 확인합니다.

서비스 활용

  • 지속적인 모니터링: 특정 주기마다 환경을 감지하거나 블랙보드 값을 업데이트해야 할 때 서비스를 사용합니다. (예: 플레이어가 시야 내에 있는지 주기적으로 확인)
  • 경량화: 서비스는 자주 실행될 수 있으므로, 내부 로직은 최대한 가볍게 유지해야 합니다. 무거운 계산은 다른 곳으로 오프로드하는 것을 고려합니다.

사용자 정의 작업 (Custom Tasks)

  • 재사용 가능한 행동: 블루프린트나 C++로 사용자 정의 작업을 만들어 복잡하거나 특정 게임 시스템과 연동되는 행동을 캡슐화합니다.
  • 명확한 입출력: 커스텀 작업은 입력 키와 성공·실패 조건을 명확히 합니다. 비동기 작업은 InProgress를 반환한 뒤 완료를 알리고, Abort 시 타이머·델리게이트·이동 요청을 정리합니다. C++의 공유 노드에 AI별 가변 상태를 무조건 저장하지 말고 노드 메모리나 인스턴싱 정책을 확인합니다.

디버깅 및 시각화

  • Gameplay Debugger: PIE에서 기본 작은따옴표 키로 열고 대상 AI와 Behavior Tree·Perception 카테고리를 선택합니다. 프로젝트의 단축키·플러그인·빌드 지원을 확인합니다.
  • Behavior Tree 에디터: 실행 중인 인스턴스를 선택해 현재 노드, 실행 이력과 Blackboard 값을 함께 확인합니다. ai.debug [이름]이나 ai.blackboard [이름]을 범용 명령으로 가정하지 않습니다.
  • Visual Logger: 10장 2절에서 다룬 Visual Logger를 사용하여 AI의 이동 경로, 목표 변경 등을 시각적으로 기록하고 재생하여 문제를 분석합니다.

C++ 측 성능 고려 사항

  • 불필요한 틱 비활성화: AI 컨트롤러나 컴포넌트의 틱을 최적화합니다. (9장 4절 CPU 최적화 참조)
  • 거리 기반 최적화: 플레이어로부터 멀리 떨어진 AI는 업데이트 빈도를 줄이거나, 행동 트리를 단순화하는 등의 최적화를 적용합니다.
  • EQS (Environment Query System): 복잡한 환경에서 AI가 최적의 위치를 찾을 때 사용됩니다. 유연하고 강력하지만, 오버헤드가 발생할 수 있으므로 필요한 경우에만 사용하고 쿼리를 최적화해야 합니다.

반응이 늦거나 멈출 때

증상먼저 확인할 경계
표적을 늦게 바꿈Perception 이벤트·키 갱신·Service 활성 브랜치와 주기
같은 행동을 반복 취소키 값 진동·Observer Aborts 범위
Task에서 멈춤비동기 완료·실패 반환·Abort 정리
Move To 실패유효 목표·NavMesh 연결·경로 요청 결과

Unreal 행동 트리는 이벤트 중심입니다. 트리 전체를 매 프레임 순회시키는 대신 필요한 키 변화와 실행 중인 서비스·작업을 관찰합니다. Epic Behavior Tree 개요의 실행·중단 의미를 기준으로 확인합니다.

그 외의 AI 관련 기술

  • State Machine (스테이트 머신): 간단한 AI 행동이나 애니메이션 제어에 효과적입니다. 행동 트리와 결합하여 사용할 수 있습니다.
  • Utility AI (유틸리티 AI): 각 행동에 점수를 부여하여 가장 높은 점수를 얻은 행동을 선택하는 방식입니다. 행동 트리보다 유연하고 상황 적응력이 높을 수 있습니다.
  • Machine Learning (머신 러닝): 최근에는 강화 학습(Reinforcement Learning) 등을 사용하여 AI를 훈련시키고 더욱 복잡하고 예측 불가능한 행동을 만들려는 시도가 활발합니다. 현재 Learning Agents 플러그인은 강화·모방 학습을 위한 경로를 제공합니다. 버전별 실험적 기능 상태와 별도 학습·런타임 추론 비용을 확인해야 합니다.

게임 AI는 NPC 판단, 이동, 감지, 디버깅 흐름을 구성하는 시스템입니다.

행동 트리와 블랙보드는 조건과 상태를 나누어 관리할 때 효과적입니다.

AI 디버거와 Visual Logger로 행동 결과를 확인하며 행동 트리 구조를 단계적으로 개선하세요.