Quick Flow
| 단계 | 확인할 것 | 실패하면 |
|---|---|---|
| Bake | NavMeshSurface의 Agent Type, 수집 대상, layer/geometry, agent radius·height | 길이 visual mesh와 다르거나 통로가 사라집니다. |
| Agent 배치 | agent.isOnNavMesh, 같은 Agent Type, Base Offset | destination 요청 전에 agent가 NavMesh 밖입니다. |
| 목적지 요청 | SetDestination 반환값 | 요청 자체가 거절됐습니다. |
| 경로 계산 | pathPending이 false가 될 때까지 | 아직 성공·실패를 판정할 수 없습니다. |
| 이동 완료 | pathStatus, remainingDistance, stoppingDistance | 부분 경로·도달·정지를 구분하지 않았습니다. |
public bool TryMoveTo(Vector3 target)
{
if (!_agent.isOnNavMesh) return false;
return _agent.SetDestination(target);
}
private bool HasReachedDestination()
{
if (_agent.pathPending) return false;
if (!_agent.hasPath) return false;
if (_agent.pathStatus != NavMeshPathStatus.PathComplete) return false;
return _agent.remainingDistance <= _agent.stoppingDistance;
}Bake와 Agent 설정
AI Navigation package의 NavMeshSurface는 이동 가능한 NavMesh를 bake하고, NavMeshAgent는 그 surface의 agent type 위에서 경로를 계산합니다. agent의 Radius와 Height는 bake 때 쓰는 agent type과 같은 통과 규칙을 가져야 합니다. NavMeshSurface는 작은 agent로 bake하고 runtime agent는 큰 반경을 쓰면 좁은 통로·문에서 경로가 없어질 수 있습니다.
| NavMeshAgent Inspector 값 | 의미 | 언제 바꾸는가 | 잘못되면 |
|---|---|---|---|
Agent Type | bake 규칙과 이동 규격 묶음 | 사람·큰 적처럼 크기가 다를 때 | agent가 맞는 NavMesh를 찾지 못합니다. |
Radius, Height, Base Offset | capsule 통과 폭·키와 mesh 위 세로 위치 | 모델과 navmesh 규격을 맞출 때 | 통로 판정, 발 위치, 장애물 회피가 어긋납니다. |
Speed, Angular Speed, Acceleration | 이동·회전·가속 한계 | 조작감과 추적 반응을 조절할 때 | 추적이 너무 늦거나 목적지 주변에서 과하게 회전합니다. |
Stopping Distance, Auto Braking | 목표 앞 정지 거리와 감속 | 공격 거리·군집 이동을 정할 때 | 목표에 부딪히거나 너무 일찍 멈춥니다. |
Area Mask, Auto Repath | 허용 NavMesh area와 invalid path 재계산 | 위험 구역·문·동적 수준을 구분할 때 | 막힌 길을 계속 믿거나 원치 않는 area로 갑니다. |
Auto Traverse Off Mesh Link | link를 자동으로 지날지 | 점프·사다리 연출을 코드가 소유할 때 | 연출을 건너뛰거나 link 앞에서 멈춥니다. |
NavMeshObstacle은 회피 또는 carving에 쓰고, NavMeshLink는 점프·사다리·문처럼 면으로 bake되지 않는 연결을 만듭니다. carve는 navmesh를 즉시 모든 frame에 다시 bake하는 일반 해법이 아니므로, 움직이는 장애물의 빈도와 agent 수를 실제 장면에서 측정합니다.
요청, 경로, 도착은 다른 상태입니다
SetDestination이 true이면 destination 계산 요청이 받아들여졌다는 뜻입니다. path는 몇 frame 뒤에 나올 수 있어 그동안 pathPending이 true입니다. pathPending이 false가 된 뒤 pathStatus가 PathComplete인지 PathPartial/PathInvalid인지 확인해야 합니다. remainingDistance가 작다고 곧바로 성공으로 처리하면 partial path의 끝을 목적지 도달로 오해할 수 있습니다.
OffMeshLink 자동 통과를 끄면 isOnOffMeshLink를 확인해 jump animation 등을 재생하고 CompleteOffMeshLink()로 완료합니다. Agent Transform을 animation 또는 Rigidbody가 동시에 움직이면 updatePosition/updateRotation 소유권도 한쪽으로 정해야 합니다.
자주 틀리는 부분
| 증상 | 원인 | 수정 방향 |
|---|---|---|
SetDestination 뒤 즉시 실패 처리 | pathPending 중입니다. | 경로 계산 완료 뒤 status를 판정합니다. |
| 좁은 문을 지나지 못함 | Bake Agent Type과 agent radius/height가 다릅니다. | 같은 규격으로 surface와 agent를 다시 확인합니다. |
| agent가 이동하지 않음 | NavMesh 위가 아니거나 path가 partial/invalid입니다. | isOnNavMesh, pathStatus, target area를 기록합니다. |
| OffMeshLink 앞에서 정지 | Auto Traverse를 끄고 완료 코드를 쓰지 않았습니다. | link 수명과 animation 완료를 연결합니다. |
| agent가 animation과 싸움 | Transform/Rigidbody/NavMeshAgent가 모두 위치를 씁니다. | position/rotation의 단일 소유자를 정합니다. |
NavMesh는 목표 위치를 넣으면 항상 도착시키는 시스템이 아닙니다. bake 규격, agent가 놓인 NavMesh, 요청 수락, path 계산, partial path, 이동 완료를 각각 확인해야 경로 오류를 코드 한 줄의 문제로 오해하지 않습니다.
참고 링크
3 sources