최종 실습: 탑다운 적 추적·전투 AI
24강. 최종 실습: 탑다운 적 추적·전투 AI
1. 이번 강의에서 해결할 문제
순찰, 추적과 공격이 각각 동작하지만 경계 조건에서 잘못 전환되거나 적이 많을 때 판단이 한 프레임에 몰립니다. 모든 수학·AI 시스템을 하나의 검증 가능한 전투 AI로 통합합니다.
2. 학습 목표
3. 핵심 개념
BT Service (0.25s ± 분산)
└─ AIController
├─ 거리 제곱 → 추적·공격 후보
├─ 내적 → 시야각
├─ Line Trace → 장애물 차폐
├─ State 결정 → Blackboard
└─ LastKnownLocation / LastSeenTime
Behavior Tree Selector
├─ Attack: 시야 + 공격 거리 + 쿨다운
├─ Chase: 목표 또는 마지막 위치로 MoveTo
└─ Patrol: Home 주변 NavMesh 위치 → MoveTo → Wait
Enemy Character
└─ 몸, CharacterMovement, 회전 보간, 공격 실행, HealthComponent
멀티플레이에서는 AI와 피해 판단의 서버 권한, 상태 복제와 시각 효과 RPC를 별도로 설계해야 합니다. 이 과정은 싱글플레이 구조와 성능 근거에 집중합니다.
4. 단계별 실습
4-1. Controller의 최종 공격 조건
C++ · 파일 경로: Source/TopDownSurvival/AI/MathAIController.cpp
bool AMathAIController::CanAttackTarget(AActor* Target) const
{
const APawn* Enemy = GetPawn();
if (!Enemy || !IsValid(Target) || !AIConfig)
{
return false;
}
const bool bInRange = UGameMathLibrary::IsWithinRange2D(
Enemy->GetActorLocation(),
Target->GetActorLocation(),
AIConfig->AttackDistance);
return bInRange && HasClearSight(Target);
}
4-2. 설정 적용과 AI별 판단 주기
19강에서는 Behavior Tree Service를 사용했습니다. 최종 프로젝트에서 적마다 다른 DataAsset 주기를 적용하려면 공유될 수 있는 BT Node 멤버를 바꾸지 않고 AIController 인스턴스의 Timer를 사용합니다. BT에서는 Update Combat Context Service를 제거하고 Blackboard Observer가 Timer 갱신에 반응하게 합니다.
C++ · 파일 경로: Source/TopDownSurvival/AI/MathAIController.cpp
void AMathAIController::StartDecisionLoop()
{
if (!AIConfig)
{
return;
}
const float Interval = FMath::Max(0.05f, AIConfig->DecisionInterval);
const float InitialDelay = FMath::FRandRange(0.0f, Interval);
GetWorldTimerManager().SetTimer(
DecisionTimerHandle,
this,
&AMathAIController::RefreshCombatContext,
Interval,
true,
InitialDelay);
}
Controller Header에 FTimerHandle DecisionTimerHandle을 추가하고 OnPossess에서 DataAsset을 적용한 뒤 StartDecisionLoop를 호출합니다. OnUnPossess와 EndPlay에서 Timer를 해제합니다. InitialDelay를 분산해 여러 적의 첫 Trace가 같은 프레임에 몰리지 않게 합니다.
4-3. C++와 Blueprint·Editor 연결
C++ 책임
- UGameMathLibrary: 방향, 거리, 내적 시야 조건
- AMathAIController: 목표 감지, 상태, Blackboard 갱신
- AMathAIEnemyCharacter: Movement, 보간, 공격과 쿨다운
- UEnemyAIConfigData: 튜닝 값
- BT Task·Service: 작은 행동과 제한된 판단 갱신
Blueprint·Editor 작업
- BB_EnemyCombat에 TargetActor, HomeLocation, PatrolLocation, HasLineOfSight, DistanceToTarget, LastKnownLocation, LastSeenTime, AIState를 확인합니다.
- BT_EnemyCombat의 Branch 순서를 Attack → Chase → Patrol로 둡니다.
- 각 Branch에 AIState 또는 Blackboard Decorator와 Observer Abort를 설정합니다.
- BP_MathAIController에 BT_EnemyCombat과 DA_AI_Normal을 연결합니다.
- BP_MathAIEnemy의 AI Controller Class와 Auto Possess AI를 확인합니다.
- NavMeshBoundsVolume이 순찰·추적 영역과 장애물을 덮는지 P로 확인합니다.
- Primitive Mesh만 사용해 플레이어, 적, 벽과 순찰 공간을 배치합니다.
4-4. PowerShell 전체 빌드
실행 위치: C:\UnrealProjects\TopDownSurvival
Set-Location C:\UnrealProjects\TopDownSurvival
$ProjectFile = (Resolve-Path .\TopDownSurvival.uproject).Path
$EngineRoot = "C:\Program Files\Epic Games\UE_5.x"
& "$EngineRoot\Engine\Build\BatchFiles\Build.bat" TopDownSurvivalEditor Win64 Development $ProjectFile -WaitMutex
UE_5.x는 설치된 엔진 폴더로 바꿉니다. Editor를 닫은 빌드와 PIE 실행을 모두 확인합니다.
5. 코드와 수학·AI가 동작하는 이유
벡터 차이는 목표 방향, 거리 제곱은 범위 후보, 내적은 시야각, Line Trace는 차폐를 판정합니다. AIController가 이 결과를 Blackboard와 상태로 바꾸고 Behavior Tree가 행동 우선순위를 선택합니다. Character는 MoveTo가 제어하는 몸과 공격 실행만 담당합니다.
| 구조 | 사용 위치 | 선택 이유 |
|---|---|---|
| Tick | 목표가 있을 때 회전 보간만 | 매 프레임 필요한 시각 변화 |
| BT Service 또는 Timer | 감지·상태 갱신 | 0.2~0.5초로 충분한 판단 |
| NavMesh·MoveTo | 순찰·추적 이동 | 장애물 경로와 도착 관리 |
| Blackboard | 목표·위치·판단 결과 | Task와 Decorator의 공통 데이터 |
| DataAsset | 거리·속도·쿨다운 | 재컴파일 없는 튜닝 |
6. 자주 하는 실수와 해결법
7. 직접 실습
8. 이해 점검 질문 3개
9. 핵심 요약
최종 실습: 탑다운 적 추적·전투 AI 미니 퀴즈
선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.
학습을 마쳤나요?
직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.