본문으로 건너뛰기
게임 수학 · 게임 AI 기초집LESSON 14

NavMesh와 AI MoveTo

난이도초급
예상 시간50분
선수지식13강의 AI 구조

14강. NavMesh와 AI MoveTo

1. 이번 강의에서 해결할 문제​

목표 방향으로 AddMovementInput만 호출하니 적이 벽에 걸립니다. 레벨 충돌에서 생성된 NavMesh 그래프를 이용해 도달 가능한 경로를 요청합니다.

2. 학습 목표​

3. 핵심 개념​

Navigation System은 레벨 충돌로부터 이동 가능한 Mesh를 만들고 Polygon 비용을 바탕으로 경로를 찾습니다. 공식 Navigation System 문서는 Tile, Generation Mode, Area Cost와 회피 기능을 설명합니다.

방향 벡터는 목표가 어디 있는지 알려 주지만 벽을 우회할 경로는 알려 주지 않습니다. AIController가 MoveTo를 요청하고 Path Following과 CharacterMovement가 실제 이동을 처리합니다.

처음 등장하는 Navigation 용어​

용어역할확인 위치
NavMesh이동 가능한 표면을 Polygon 연결 관계로 표현한 길찾기 데이터Editor에서 P를 눌렀을 때 보이는 초록 영역
NavMeshBoundsVolumeNavMesh를 생성할 공간 범위Place Actors와 레벨 Viewport
Navigation AgentAI의 반지름·높이·이동 능력 규격Project Settings와 Character Capsule
경로(Path)시작점부터 목적지까지 연결된 NavMesh 구간AI Debugger 또는 Path Following 로그
Acceptance Radius목적지에 도착했다고 인정할 거리MoveToLocation 두 번째 인자
AIController목표와 행동을 결정하고 이동을 요청하는 객체Pawn을 Possess한 Controller

NavMesh가 초록색이라고 모든 AI가 반드시 지나갈 수 있는 것은 아닙니다. Agent 반지름보다 좁은 통로, NavMesh가 끊긴 높이 차, 잘못된 Capsule 설정은 경로 실패를 만듭니다. 먼저 공간 데이터를 확인한 뒤 C++ 이동 코드를 고쳐야 원인과 해결이 연결됩니다.

4. 단계별 실습​

Unreal Editor에서 가장 작은 길찾기 환경 만들기​

  1. 바닥에 Collision이 있는지 확인하고 Place Actors에서 NavMeshBoundsVolume을 배치해 바닥 전체를 감쌉니다.
  2. Viewport에서 P를 누르거나 콘솔에서 show Navigation true를 실행해 초록색 이동 가능 영역을 확인합니다.
  3. Collision이 있는 벽을 시작점과 TargetPoint 사이에 둡니다. 초록 영역이 벽을 통과하지 않고 주변으로 이어져야 합니다.
  4. Enemy Character의 Auto Possess AI 또는 Spawned 설정과 AI Controller Class를 확인합니다. Play 중 Controller가 AMathAIController여야 합니다.
  5. Capsule 크기와 Navigation Agent Radius가 통로 폭에 맞는지 확인합니다.

C++ · 파일 경로: Source/TopDownSurvival/AI/MathAIController.h · 이동 API

MathAIController.h · 추가
UFUNCTION(BlueprintCallable, Category = "AI|Movement")
bool MoveToReachableLocation(FVector Destination, float AcceptanceRadius);

C++ · 파일 경로: Source/TopDownSurvival/AI/MathAIController.cpp

MathAIController.cpp · MoveTo
#include "Navigation/PathFollowingComponent.h"
#include "NavigationSystem.h"

bool AMathAIController::MoveToReachableLocation(
FVector Destination, float AcceptanceRadius)
{
if (!GetPawn())
{
return false;
}

FNavLocation Projected;
UNavigationSystemV1* Navigation =
FNavigationSystem::GetCurrent<UNavigationSystemV1>(GetWorld());
if (!Navigation ||
!Navigation->ProjectPointToNavigation(Destination, Projected))
{
UE_LOG(LogTemp, Warning, TEXT("Destination is outside NavMesh"));
return false;
}

const EPathFollowingRequestResult::Type Result = MoveToLocation(
Projected.Location,
FMath::Max(1.0f, AcceptanceRadius),
true,
true,
true,
false,
nullptr,
true);

return Result != EPathFollowingRequestResult::Failed;
}

코드와 반환값 이해하기​

  1. GetPawn()이 없으면 Controller가 움직일 대상이 없으므로 즉시 실패합니다.
  2. GetCurrent<UNavigationSystemV1>(GetWorld())는 현재 World의 Navigation System을 가져옵니다. Editor의 다른 World나 초기화 전에는 없을 수 있습니다.
  3. ProjectPointToNavigation은 임의의 Destination을 가까운 NavMesh 점으로 투영합니다. 함수가 실패하면 목표 주변에 사용 가능한 NavMesh가 없다는 뜻입니다.
  4. Acceptance Radius는 최소 1로 제한해 음수나 0으로 생길 수 있는 불필요한 정밀 도착 요구를 피합니다.
  5. 이어지는 인자는 순서대로 Stop on Overlap, Pathfinding 사용, 목적지 투영, Strafe 허용, 기본 Query Filter, Partial Path 허용 정책입니다. bool 인자가 많으므로 호출 위에 정책 주석을 남기는 편이 안전합니다.
  6. MoveToLocation은 이동이 끝날 때까지 기다리지 않습니다. 요청 직후 Failed, AlreadyAtGoal, RequestSuccessful 중 하나를 반환합니다.
  7. 현재 wrapper는 Failed가 아니면 true입니다. Partial Path를 허용했으므로 요청은 성공해도 목표 바로 앞까지 도달하지 못할 수 있습니다. 실제 도착·실패는 OnMoveCompleted 또는 Behavior Tree Task 결과에서 확인합니다.

Blueprint에서 요청하고 화면 결과 확인​

BP_MathAIController 또는 테스트용 Actor에서 레벨의 TargetPoint 위치로 MoveToReachableLocation을 한 번 호출합니다. 반환값과 목적지를 Print String으로 남깁니다.

  • TargetPoint가 같은 초록 영역 안에 있으면 true가 나오고 AI가 벽을 돌아 이동해야 합니다.
  • Pawn이 이미 Acceptance Radius 안이면 true지만 눈에 띄는 이동이 없을 수 있습니다.
  • NavMesh에서 멀리 떨어진 목표는 투영에 실패해 Warning 로그와 false가 나와야 합니다.

테스트용 BeginPlay 호출은 확인 후 제거합니다. Tick마다 재요청하면 경로를 불필요하게 다시 계산합니다.

5. 코드와 수학·AI가 동작하는 이유​

ProjectPointToNavigation은 임의 목표를 가까운 NavMesh 위치로 투영합니다. MoveToLocation은 경로 요청 결과를 즉시 반환하며 실제 도착은 비동기입니다. 도착 후 행동은 Behavior Tree Task 완료나 MoveCompleted 이벤트로 연결해야 합니다.

6. 자주 하는 실수와 해결법​

7. 직접 실습​

실습 목표​

NavMesh 안팎과 장애물 조건을 바꾸며 요청 승인과 실제 도착이 서로 다른 단계임을 확인합니다.

시작 전 상태​

Enemy Character가 AMathAIController에 Possess되고, 바닥의 NavMesh가 초록색으로 보이며, 같은 영역에 TargetPoint가 하나 있어야 합니다.

1단계: 따라 하기​

장애물이 없는 같은 NavMesh 안으로 요청합니다. 함수 반환 true, AI 이동 시작, Acceptance Radius 안에서 정지하는 세 결과를 순서대로 확인합니다.

2단계: 값 바꿔 보기​

Acceptance Radius를 10과 200으로 바꿉니다. 200일 때는 목표에서 더 먼 곳에 멈춰도 도착으로 처리될 수 있습니다. “정확한 한 점”이 아니라 허용 반경 정책임을 화면 거리로 비교합니다.

3단계: 직접 적용​

목표를 벽 뒤, NavMesh 밖, Agent보다 좁은 통로 뒤에 각각 둡니다. 다음 네 열로 표를 만드세요: P 시각화, 즉시 반환, 실제 이동, 완료 결과. 가능하면 OnMoveCompleted에서 Result Code를 로그로 남겨 요청 승인과 최종 결과를 분리합니다.

4단계: 스스로 확인​

막혔을 때​

증상먼저 확인할 곳해결
초록 영역이 전혀 없음Bounds Volume, 바닥 Collision, Navigation 생성 설정Volume이 바닥을 감싸는지와 바닥이 Navigation에 영향을 주는지 확인합니다.
함수가 즉시 falsePawn, Navigation System, 목적지 투영어느 조건에서 반환했는지 Warning 로그를 나눠 추가합니다.
true지만 AI가 움직이지 않음이미 도착 범위, Possess, Movement ComponentPawn-Controller 관계와 Acceptance Radius를 확인합니다.
벽 앞에서 멈춤경로가 끊기거나 Partial Path만 존재P 시각화, Agent Radius, 벽 주변 연결 영역을 확인합니다.

8. 이해 점검 질문 3개​

9. 핵심 요약​

다음 강의 연결​

다음 강의: Blackboard에서는 이동할 Target Actor와 Patrol Location을 AI별 판단 데이터로 저장해 Behavior Tree의 조건과 행동이 같은 목표를 읽게 합니다.

MINI QUIZ

NavMesh와 AI MoveTo 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“NavMesh와 AI MoveTo”에서 오류나 데이터 손실을 줄이는 선택은 무엇인가요?
  2. 문제 2‘MoveTo를 Tick마다 재요청’ 실수를 판단할 때 “NavMesh와 AI MoveTo” 강의가 제시한 기준은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

14강. NavMesh와 AI MoveTo 미완료 상태