게임에서 적 캐릭터는 단순히 플레이어를 따라가기만 해서는 자연스럽게 보이지 않는다. 평소에는 주변을 순찰하고, 플레이어를 발견하면 추격하며, 시야에서 놓치면 마지막으로 목격한 장소를 조사해야 한다. 상황에 따라 적절한 엄폐 장소를 선택할 수도 있어야 한다.
이러한 여러 행동을 조건문만으로 구현하면 코드가 빠르게 복잡해진다.
플레이어를 발견했는가?
발견했다면 추격한다.
발견하지 못했다면 순찰한다.
추격 중 플레이어를 놓쳤는가?
놓쳤다면 마지막 위치를 조사한다.
공격받았는가?
공격받았다면 공격자를 찾는다.
행동이 추가될수록 조건문은 서로 얽히고, 현재 AI가 어떤 판단을 내리고 있는지 확인하기 어려워진다.
언리얼 엔진은 이런 문제를 해결하기 위해 다음과 같은 AI 시스템을 제공한다.
AI Perception
↓
Blackboard
↓
Behavior Tree
↓
EQS
↓
이동·추격·공격
각 시스템은 독립적인 기능을 담당하지만 서로 연결되어 하나의 AI를 구성한다.
1. 언리얼 엔진 AI의 전체 구조
언리얼 엔진에서 일반적인 적 AI는 다음 요소로 구성한다.
- Character 또는 Pawn
- AI Controller
- Blackboard
- Behavior Tree
- AI Perception
- Environment Query System
Character는 실제 게임 월드에 존재하는 몸체다. 이동하고 애니메이션을 재생하며 공격을 수행한다.
AI Controller는 Character를 조종하는 두뇌 역할을 한다. 플레이어가 Player Controller를 통해 캐릭터를 조작하는 것처럼 AI 캐릭터는 AI Controller의 제어를 받는다.
Behavior Tree는 AI가 어떤 행동을 실행할지 결정한다.
Blackboard는 Behavior Tree가 판단에 사용할 정보를 저장한다.
AI Perception은 시각과 청각 등의 감각 정보를 수집한다.
EQS는 주변 환경을 검사하여 이동하거나 숨기에 가장 적절한 위치를 선택한다.

Player
↓ 감지
AI Perception
↓ 정보 저장
Blackboard
↓ 조건 확인
Behavior Tree
↓ 명령
AI Controller
↓ 조종
AI Character
2. Behavior Tree란 무엇인가
Behavior Tree는 AI의 행동을 트리 형태로 구성하는 시스템이다.
예를 들어 적 AI가 다음 행동을 수행한다고 가정한다.
플레이어가 보이면 추격한다.
플레이어가 보이지 않으면 순찰한다.
이를 비헤이비어 트리로 표현하면 다음과 같다.
Root
└─ Selector
├─ Sequence: 플레이어 추격
│ ├─ 플레이어가 보이는가?
│ ├─ 플레이어 방향으로 회전
│ └─ 플레이어에게 이동
│
└─ Sequence: 순찰
├─ 순찰 위치 선택
└─ 순찰 위치로 이동
언리얼 엔진의 비헤이비어 트리는 기본적으로 위에서 아래로 내려가며, 같은 높이에서는 왼쪽에서 오른쪽 순서로 실행한다. 따라서 왼쪽에 있는 브랜치가 더 높은 우선순위를 가진다.
언리얼 엔진의 비헤이비어 트리는 불필요한 조건을 매 프레임 검사하는 방식보다 이벤트 중심으로 동작하도록 설계되어 있다. 블랙보드 값이 변경되면 관련 브랜치를 중단하고 우선순위가 높은 행동으로 전환할 수 있다. 언리얼 엔진 Behavior Tree 개요

Root
↓
Selector
↙ ↘
플레이어 추격 순찰
HasTarget = true HasTarget = false
3. Selector와 Sequence의 차이
비헤이비어 트리에서 가장 중요한 Composite 노드는 Selector와 Sequence다.
Selector
Selector는 여러 행동 중 성공할 수 있는 하나를 선택한다.
왼쪽 자식부터 실행하며 성공한 브랜치가 발견되면 나머지 브랜치는 실행하지 않는다.
Selector
├─ 플레이어를 추격할 수 있는가?
├─ 마지막 위치를 조사할 수 있는가?
└─ 순찰한다.
플레이어를 추격할 수 있다면 첫 번째 브랜치를 실행한다. 추격할 수 없다면 두 번째 브랜치를 검사한다. 두 번째도 실행할 수 없다면 마지막 순찰 브랜치를 실행한다.
프로그래밍의 if, else if, else 구조와 비슷하다.
if (CanChasePlayer)
{
ChasePlayer();
}
else if (CanInvestigate)
{
Investigate();
}
else
{
Patrol();
}
Sequence
Sequence는 여러 행동을 순서대로 실행한다.
모든 자식이 성공해야 Sequence 전체가 성공한다. 중간 행동이 실패하면 이후 행동은 실행하지 않는다.
Sequence: 플레이어 공격
├─ 플레이어에게 이동한다.
├─ 공격 범위인지 확인한다.
├─ 플레이어 방향으로 회전한다.
└─ 공격한다.
플레이어에게 이동하지 못하면 공격 범위 확인과 공격 행동은 실행하지 않는다.
Selector가 “어떤 행동을 할 것인가”를 선택한다면, Sequence는 “선택한 행동을 어떤 순서로 수행할 것인가”를 나타낸다. Behavior Tree Quick Start Guide

| Selector | 하나가 성공할 때까지 실행한다 | if / else if / else |
| Sequence | 하나가 실패할 때까지 순서대로 실행한다 | A && B && C |
4. Task, Decorator, Service
비헤이비어 트리에는 Composite 외에도 세 가지 중요한 노드가 있다.
Task
Task는 AI가 실제로 수행할 행동이다.
Move To
Wait
Play Animation
Run EQS Query
Attack
Find Patrol Location
Move To는 지정된 액터나 위치로 이동하는 Task다. 공격이나 순찰 위치 선택처럼 게임 고유의 행동은 Blueprint 또는 C++로 커스텀 Task를 만들어 구현할 수 있다.
Decorator
Decorator는 브랜치가 실행될 수 있는지 검사하는 조건이다.
HasTarget == true
CanAttack == true
Health <= 30
IsPlayerVisible == true
Decorator 조건이 거짓이면 해당 브랜치에 진입하지 않는다.
또한 Observer Aborts 설정을 이용하면 블랙보드 값이 변했을 때 현재 실행 중인 브랜치를 중단할 수 있다. 예를 들어 순찰 중 HasTarget이 참으로 변경되면 순찰을 중단하고 추격 브랜치로 전환한다.
Service
Service는 특정 브랜치가 실행되는 동안 주기적으로 정보를 갱신한다.
플레이어와의 거리 확인
공격 가능 여부 갱신
가장 가까운 적 검색
주변 위험도 계산
모든 기능을 Service의 Tick에 넣으면 주기적인 연산이 많아질 수 있다. 감지 결과처럼 이벤트로 받을 수 있는 정보는 AI Perception 이벤트를 이용하고, 반드시 주기적으로 확인해야 하는 값만 Service에서 갱신하는 편이 좋다.

Composite → 흐름을 제어한다.
Task → 행동을 실행한다.
Decorator → 실행 조건을 검사한다.
Service → 정보를 주기적으로 갱신한다.
5. Blackboard는 AI의 기억 공간이다
Blackboard는 AI가 판단에 사용할 값을 저장하는 데이터 공간이다.
다음과 같은 Key를 만들 수 있다.
| TargetActor | Object | 현재 추적 중인 플레이어 |
| HasLineOfSight | Bool | 플레이어가 시야에 보이는지 여부 |
| LastKnownLocation | Vector | 마지막으로 확인한 플레이어 위치 |
| PatrolLocation | Vector | 다음 순찰 위치 |
| CanAttack | Bool | 현재 공격할 수 있는지 여부 |
Behavior Tree는 직접 모든 정보를 찾기보다 Blackboard 값을 읽어 행동을 결정한다.
HasLineOfSight == true
↓
TargetActor에게 이동한다.
HasLineOfSight == false
↓
LastKnownLocation으로 이동한다.
공식 문서에서도 Behavior Tree가 실행할 브랜치를 결정하기 위해 Blackboard Key를 사용한다고 설명한다. 언리얼 엔진 Behavior Tree 문서
Blackboard는 단순한 변수 모음이 아니다. AI Perception, Behavior Tree, EQS 사이에서 정보를 전달하는 공용 저장소에 가깝다.

AI Perception ──쓰기──▶ Blackboard ◀──쓰기── EQS
│
읽기
▼
Behavior Tree
6. AI Perception으로 플레이어를 감지한다
AI Perception은 AI에게 시각, 청각과 같은 감각 기능을 제공한다.
대표적인 Sense는 다음과 같다.
- AI Sight: 시야 안의 액터를 감지한다.
- AI Hearing: 발생한 소리를 감지한다.
- AI Damage: 피해를 준 대상을 감지한다.
- AI Touch: 접촉한 대상을 감지한다.
AI Controller에 AI Perception Component를 추가하면 감지 이벤트를 받을 수 있다.
플레이어를 시각으로 감지한 경우의 흐름은 다음과 같다.
플레이어가 시야에 들어온다.
↓
On Target Perception Updated
↓
Successfully Sensed 확인
↓
TargetActor = 플레이어
HasLineOfSight = true
↓
Behavior Tree의 추격 브랜치 실행
반대로 플레이어를 놓치면 다음처럼 처리할 수 있다.
Successfully Sensed = false
↓
LastKnownLocation 저장
↓
HasLineOfSight = false
↓
마지막 목격 위치 조사
AI Perception Component는 자극을 수집하고, 감지 결과가 변경되면 이벤트를 통해 Blueprint 로직이나 Behavior Tree가 사용하는 값을 갱신할 수 있다. AI Perception 공식 문서

AI 시야 범위
╱ ╲
Enemy ───────▶ Player
│
└─ On Target Perception Updated
↓
HasLineOfSight = true
7. EQS로 최적의 위치를 찾는다
Behavior Tree가 “무엇을 할 것인가”를 정한다면, EQS는 “어디에서 할 것인가”를 계산한다.
예를 들어 AI가 엄폐할 위치를 찾는다고 가정한다.
주변에 이동 가능한 여러 후보 지점을 생성한 뒤 다음 조건으로 평가한다.
플레이어에게서 너무 가깝지 않은가?
AI가 이동할 수 있는 위치인가?
플레이어의 시야를 차단할 수 있는가?
공격할 수 있는 시야가 확보되는가?
EQS는 크게 세 요소로 구성한다.
Generator
검사할 후보 위치나 액터를 생성한다.
AI 주변의 원형 지점
플레이어 주변의 이동 가능 지점
레벨에 배치된 엄폐물
Context
거리나 방향을 계산할 때 기준이 되는 대상이다.
현재 AI
플레이어
마지막 목격 위치
특정 목표 액터
Test
각 후보가 조건을 만족하는지 검사하고 점수를 부여한다.
거리 검사
시야 검사
이동 가능 여부 검사
경로 비용 검사
모든 Test를 통과한 후보 중 가장 높은 점수를 얻은 위치를 최종 결과로 선택한다.
후보 위치 생성
↓
이동 불가능한 위치 제거
↓
플레이어와의 거리 평가
↓
시야 확보 여부 평가
↓
가장 높은 점수의 위치 선택
EQS Query는 Behavior Tree의 Run EQS Query Task에서 실행할 수 있으며, 결과 위치를 Blackboard에 저장한 뒤 Move To Task로 이동할 수 있다. EQS 공식 문서

후보 A 20점
후보 B 80점 Player
AI 후보 C 45점
후보 D 제외
최종 선택 → 후보 B
8. 잠입 게임 적 AI의 전체 동작
지금까지 살펴본 시스템을 하나로 연결하면 다음과 같은 AI를 만들 수 있다.
평상시
TargetActor가 없다.
↓
EQS로 순찰 위치를 찾는다.
↓
PatrolLocation에 저장한다.
↓
Move To로 이동한다.
플레이어 발견
AI Perception이 플레이어를 감지한다.
↓
TargetActor와 HasLineOfSight를 갱신한다.
↓
Decorator가 변경을 감지한다.
↓
순찰 브랜치를 중단한다.
↓
플레이어 추격 브랜치를 실행한다.
플레이어를 놓친 경우
HasLineOfSight = false
↓
마지막 목격 위치로 이동한다.
↓
주변을 일정 시간 조사한다.
↓
플레이어를 찾지 못하면 다시 순찰한다.
전투 위치 선택
Run EQS Query
↓
플레이어와 거리를 유지하면서
시야가 확보되는 위치를 찾는다.
↓
결과를 Blackboard에 저장한다.
↓
해당 위치로 이동한 뒤 공격한다.

플레이어 발견
순찰 ─────────────▶ 추격
▲ │
│ │ 시야 상실
│ ▼
└─────────────── 마지막 위치 조사
발견 실패
9. 구현할 때 주의할 점
Blackboard Key를 지나치게 많이 만들지 않는다
모든 임시 값을 Blackboard에 넣으면 데이터의 의미를 파악하기 어려워진다. 여러 Task와 시스템이 공유해야 하는 정보만 Blackboard에 저장한다.
Service의 갱신 주기를 조절한다
Service는 필요한 주기로만 실행한다. 매 프레임 실행할 필요가 없는 거리 계산이나 목표 탐색을 지나치게 자주 수행하면 AI 수가 증가했을 때 성능에 영향을 줄 수 있다.
왼쪽 브랜치에 높은 우선순위를 배치한다
언리얼 엔진의 비헤이비어 트리는 왼쪽에서 오른쪽 순서로 실행한다.
Selector
├─ 사망 처리
├─ 피격 대응
├─ 전투
└─ 순찰
즉시 처리해야 하는 행동일수록 왼쪽에 배치하는 것이 자연스럽다.
감지와 판단을 분리한다
AI Perception은 정보를 감지하고, Blackboard는 정보를 저장하며, Behavior Tree는 행동을 결정하도록 역할을 분리한다.
AI Perception 이벤트 안에서 이동과 공격까지 모두 처리하면 시스템 간 책임이 뒤섞이게 된다.
마무리
비헤이비어 트리는 AI의 모든 기능을 직접 처리하는 시스템이 아니다. 여러 AI 시스템을 연결하여 행동의 우선순위와 실행 흐름을 관리하는 역할을 한다.
핵심 관계는 다음과 같이 정리할 수 있다.
AI Perception
→ 무엇을 보고 들었는지 감지한다.
Blackboard
→ AI가 알고 있는 정보를 저장한다.
Behavior Tree
→ 현재 실행할 행동을 결정한다.
EQS
→ 행동을 수행하기 가장 좋은 위치나 대상을 찾는다.
AI Controller
→ 결정된 행동을 Character에게 실행시킨다.
이 구조를 이해하면 단순한 순찰 AI부터 플레이어를 추적하고 엄폐물을 활용하는 전투 AI까지 단계적으로 확장할 수 있다.
영상은 2021년에 공개된 자료이므로 현재 언리얼 엔진 버전에서는 일부 메뉴와 에디터 화면이 달라질 수 있다. 하지만 Behavior Tree, Blackboard, AI Perception, EQS가 연결되는 기본 구조는 현재 공식 문서에서도 동일하게 설명한다.
'언리얼엔진 > 개념·이론' 카테고리의 다른 글
| 언리얼 엔진의 GAS란 무엇일까? (0) | 2026.07.20 |
|---|---|
| [Unreal Engine 네트워크] HasAuthority()와 IsLocallyControlled()는 무엇이 다른가? (0) | 2026.07.15 |