본문으로 건너뛰기

안동민 개발노트

본문 시작

AI와 행동 트리

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

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

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

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

Behavior Tree 구조

AI Controller가 인지와 이동을 담당하고, Blackboard가 상태를 저장하며, Behavior Tree가 행동 선택을 수행한다.

  1. AI Controller

    Perception, MoveTo, Behavior Tree 실행을 담당하는 두뇌 역할이다.

  2. Blackboard

    목표 위치, 플레이어 감지 여부 같은 판단 데이터를 보관한다.

  3. Behavior Tree

    조건과 작업을 계층적으로 배치해 다음 행동을 결정한다.

  4. Composite

    Selector 또는 Sequence로 가지의 선택 순서를 구성

  5. Decorator

    실행 조건을 검사

  6. Task

    Move To, Wait, Attack 수행


게임 AI의 기본 개념

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

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

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


AI 컨트롤러 (AI Controller)

모든 AI 캐릭터는 자신의 행동을 제어하는 AI 컨트롤러를 가집니다.

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

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

내비게이션 메시 (Navigation Mesh)

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

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

  • 작동 방식: 에디터에서 P 키를 누르면 내비게이션 메시(기본적으로 녹색)가 시각화됩니다. AI는 이 메시 위에서만 이동 경로를 계산할 수 있습니다.
  • 활용: AI가 복잡한 환경에서 장애물을 회피하며 목표 지점까지 도달할 수 있도록 해줍니다.

행동 트리 (Behavior Tree)

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

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

행동 트리의 핵심 구성 요소

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

블랙보드 (Blackboard)

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

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

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

AI Controller가 인지와 이동을 관리하고, Behavior Tree가 행동 선택을 구성하며, Blackboard가 목표 위치와 상태값을 공유합니다.

  1. 성공하는 첫 행동 선택

    Selector 성공하는 첫 행동 선택 우선순위가 높은 행동부터 시도하고 성공하면 멈춥니다.

  2. 모든 단계가 성공해야 함

    Sequence 모든 단계가 성공해야 함 찾기, 이동, 공격처럼 순서가 중요한 흐름에 맞습니다.

  3. 실행 조건 검사

    Decorator 실행 조건 검사 거리, 쿨다운, 블랙보드 값으로 브랜치 진입을 제어합니다.

  4. 주기적 상태 갱신

    Service 주기적 상태 갱신 플레이어 위치나 시야 감지를 너무 자주 돌지 않게 조절합니다.

  5. 실제 행동 수행

    Task 실제 행동 수행 Move To, Wait, Attack 같은 작은 실행 단위를 만듭니다.


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

계층적 설계

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

블랙보드 활용

  • 중앙 집중식 데이터: 모든 AI 관련 데이터를 블랙보드에 집중시켜 관리합니다.
  • 명확한 키 정의: 블랙보드 키의 이름을 명확하게 정의하여 어떤 정보를 저장하는지 쉽게 알 수 있도록 합니다.
  • 데이터 타입 일치: 키에 저장되는 데이터 타입이 일치하도록 주의합니다.

데코레이터의 현명한 사용

  • 조건부 실행: 데코레이터는 불필요한 행동 트리의 순회를 막아 성능을 향상시키고 로직을 명확하게 합니다.
  • 재평가(Observer Aborts): 데코레이터의 Observer Aborts 설정을 통해 조건이 변경될 때 현재 실행 중인 행동 트리 브랜치를 중단하고 재평가할지 결정합니다. 이는 AI의 반응성을 높이는 데 중요합니다.
    • None: 조건이 변경되어도 현재 브랜치 중단 안함.
    • Self: 이 데코레이터가 붙은 노드만 재평가.
    • Lower Priority: 현재 실행 중인 브랜치보다 우선순위가 낮은 브랜치만 재평가.
    • Both: 현재 브랜치와 낮은 우선순위 브랜치 모두 재평가.

서비스 활용

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

사용자 정의 작업 (Custom Tasks)

  • 재사용 가능한 행동: 블루프린트나 C++로 사용자 정의 작업을 만들어 복잡하거나 특정 게임 시스템과 연동되는 행동을 캡슐화합니다.
  • 명확한 입출력: 커스텀 작업은 명확한 입력(블랙보드 키)과 출력(성공/실패)을 가져야 합니다.

디버깅 및 시각화

  • AI Debugger (AIDebugger): 언리얼 에디터의 Window -> Developer Tools -> AIDebugger를 사용하여 실행 중인 AI 행동 트리의 현재 상태, 블랙보드 값, 인지 시스템 등을 시각적으로 확인하고 디버깅할 수 있습니다.
  • 콘솔 명령
    • ai.debug [PawnName/ControllerName]: 특정 AI의 디버그 정보 표시.
    • ai.blackboard [PawnName/ControllerName]: AI의 현재 블랙보드 값 표시.
    • showdebug ai: AI 인지 시스템 정보 오버레이.
  • Visual Logger: 10장 2절에서 다룬 Visual Logger를 사용하여 AI의 이동 경로, 목표 변경 등을 시각적으로 기록하고 재생하여 문제를 분석합니다.

C++ 측 성능 고려 사항

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

아래 다이어그램은 행동 트리를 설계한 뒤 반응성, 갱신 비용, 디버깅 지점을 함께 점검하는 기준을 정리한 것입니다.

반응성은 매 프레임 순회가 아니라 관찰 범위·갱신 주기·Task 종료가 만든다

언리얼 행동 트리는 Blackboard 변화에 반응하는 이벤트 중심 구조입니다. 키 변경부터 Abort와 Task 결과까지 한 경로로 추적합니다.

  1. 감각·게임 사건

    EVENT 표적 발견·피격·소멸

  2. Blackboard 갱신

    WRITE 키의 단일 소유자가 변경

  3. Decorator 재평가

    OBSERVE 조건과 Abort 범위 확인

  4. 우선순위 분기

    SELECT 왼쪽부터 실행 후보 선택

  5. Task 결과 반환

    FINISH Progress → Success / Fail / Abort

  6. 느림

    Blackboard 갱신 지연 Service가 활성 branch에 있는지, Interval이 목표보다 긴지 봅니다. writer · interval · branch

  7. 떨림

    반복 취소·재선택 키 노이즈와 Self·Lower Priority·Both의 범위를 줄입니다. key churn · abort scope

  8. 멈춤

    Task가 Progress에 잔류 완료 호출과 Abort 시 비동기 정리를 함께 확인합니다. finish · cancel · cleanup


그 외의 AI 관련 기술

  • State Machine (스테이트 머신): 간단한 AI 행동이나 애니메이션 제어에 효과적입니다. 행동 트리와 결합하여 사용할 수 있습니다.
  • Utility AI (유틸리티 AI): 각 행동에 점수를 부여하여 가장 높은 점수를 얻은 행동을 선택하는 방식입니다. 행동 트리보다 유연하고 상황 적응력이 높을 수 있습니다.
  • Machine Learning (머신 러닝): 최근에는 강화 학습(Reinforcement Learning) 등을 사용하여 AI를 훈련시키고 더욱 복잡하고 예측 불가능한 행동을 만들려는 시도가 활발합니다. 언리얼 엔진은 Reinforcement Learning 플러그인과 외부 ML 라이브러리와의 연동을 지원합니다.

아래 다이어그램은 AI 판단 구조를 선택할 때 행동 트리, 스테이트 머신, 유틸리티 방식, 학습 기반 방식을 어떤 기준으로 나눌지 정리한 것입니다.

AI 구조는 상태 수, 목표 재평가, 디버깅 방식으로 고른다

적이 복잡해 보인다고 항상 Behavior Tree가 답은 아니다. 판단 구조는 문제의 모양에 맞춰 고른다.

구조맞는 상황디버깅 단서
State Machine상태가 적고 전환 규칙이 명확하다전이 로그와 현재 상태
Behavior Tree목표 계층과 조건 분기가 자주 바뀐다Blackboard 값과 Decorator 실패 이유
Utility AI여러 욕구를 점수로 비교해야 한다행동별 점수와 최고 점수 선택 이유
Learning규칙화보다 데이터 패턴이 중요하다입력 데이터 품질, 추론 비용, 지표

아래 다이어그램은 AI가 실행 중일 때 감지, 블랙보드 갱신, 행동 트리 재평가, 이동과 디버깅 증거가 한 루프로 이어지는 과정을 정리한 것입니다.

행동 트리 재평가

AIController가 감지한 세계 상태는 Blackboard에 모이고, Decorator와 Service가 실행 흐름을 바꾸며, Task는 이동과 전투를 실제 액션으로 옮깁니다.

  1. 자극을 수집한다

    Perception AIPerceptionComponent가 플레이어 위치, 소리, 피해 발생을 AIController에 전달합니다.

  2. 판단 데이터 갱신

    Blackboard 목표 액터, 목표 위치, 경계 상태, 재사용 대기시간을 키 타입에 맞게 저장합니다.

  3. 중단 범위 결정

    Decorator Observer Aborts로 현재 행동 유지와 상위 브랜치 전환을 정합니다.

  4. 행동을 실행한다

    Task Move To, Run EQS, 공격 Task가 성공/실패를 반환해 트리를 닫습니다.

  5. 이유 확인

    Debug 현재 노드, 블랙보드 값, 이동 경로를 함께 보아 AI가 왜 멈췄는지 좁힙니다.

  6. 자주 바뀌는 값은 Service로 관리한다

    반응성 플레이어 거리나 시야 여부처럼 계속 변하는 조건은 Tick Interval을 두고 갱신해 트리 순회 비용을 제어합니다.

  7. 커스텀 Task는 입출력 고정

    재사용성 블랙보드 키, 성공 조건, 실패 조건을 명확히 하면 C++ Task와 블루프린트 Task를 같은 트리에서 안전하게 섞을 수 있습니다.


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

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

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

Behavior Tree 문제는 감지, 블랙보드, 분기 조건 순서로 좁힌다

AI가 멈춘 것처럼 보이면 트리 전체보다 입력 값이 어느 단계에서 끊겼는지 먼저 본다.

순서확인할 계약막혔을 때 볼 것
SensePerception, 거리, Line Trace가 필요한 키를 갱신한다감지 범위와 시야 조건
BlackboardTargetActor, HasLineOfSight 같은 값만 보관한다키 이름, 타입, 갱신 시점
Decorator조건은 행동을 숨기는 필터로만 둔다Abort 조건과 실패 이유
Task / Service짧은 실행은 Task, 지속 관찰은 Service에 둔다NavMesh와 AI Debugger