
경로 탐색과 관련해 알아보면서 Recast Nav와 이동 로직에 대해 많이 이해하게 되었다.
먼저 Recast NavMesh의 Nav Agent Radius 설정은 단순 충돌 크기 설정이 아니었다.

이 값은 “해당 크기의 객체가 실제 지나갈 수 있는 공간만 Nav로 빌드”한다는 의미였다.
즉 Agent 크기가 크면:
그래서 최적화를 고려한다면:
Nav를 사용하는 객체들 중 가장 작은 크기 기준으로 Nav를 빌드하는 것이 유리
하다는 것도 알게 되었다.
그리고 CharacterMovementComponent의 Navigation 설정도 새롭게 이해했다.

Update Nav Agent With Owner's Collision 옵션을 활성화하면 해당 액터의 콜리젼을 기반으로 실제 이동 가능한 경로를 계산한다.
아래 값들을 -1로 두면 별도 Agent 값을 쓰지 않고, 현재 Collision 크기를 그대로 사용한다는 의미였다.
원래 의도했던 방식이 정확히 이 구조였기 때문에,
추가 수정 없이 그대로 사용하기로 했다.
처음에는 AI가 이동하면서 계속 다음 경로를 계산할 것이라고 생각했는데 아니었다.
일반적인 MoveToLocation()은 시작 시점에 목적지까지 전체 경로를 한 번 계산한다.
즉, 매우 먼 거리라면 초기 계산 비용이 커질 수 있지만 이동 중에는 계속 재탐색하지 않는다.
다만 NavMesh 갱신, 장애물 변화같은 상황이 발생하면 그때 다시 계산한다.
그렇다면 궁금했던 점이 있었다.
“처음 계산 시 경로가 완전히 없으면 AI는 가만히 있을까?”
기본적으로 AITypes.h에 아래와 같이 PartialPath가 정의되어 있다.
USTRUCT()
struct FAIMoveRequest
{
/** pathfinding: allow using incomplete path going toward goal but not reaching it */
uint32 bAllowPartialPath : 1;
}
즉 목적지까지 완전한 경로가 없어도, 갈 수 있는 최대 지점까지는 이동하려고 한다.
재미있었던 점은, 경로가 막혀 부분경로만 간 상황에도 MoveTo()함수는 성공을 반환한다는 점이었다.
“도달 가능한 최종 지점”까지는 정상적으로 도착했기 때문이다.
그리고 이를 이용해 두 가지의 상황에 대한 AI로직을 구현했다.
두 상황 다 성공을 반환하고, 이 때 공격 State로 전환되게 구현하여 자연스러운 행동로직을 구현할 수 있었다.
이후, 장애물이 파괴되어 Nav가 다시 연결되면, AI는 정상적으로 코어까지 이동하는 것을 확인할 수 있었다.