[UE5] NavModifierVolume과 RVO

재석 블로그·2025년 4월 23일
post-thumbnail

이전 포스팅에선 NavMeshBoundsVolume을 레벨에 배치하여 AIController가 이동할 수 있는 공간을 설정·확인하고, Navigation Invoker 컴포넌트를 캐릭터에 추가하여 내브메시의 리소스 사용을 최적화하는 방법에 대해서 알아봤다.

이번 포스팅에선 NavModifierVolume을 이용해 AI의 경로탐색 알고리즘에 동적으로 비용을 부여하는 방법에 대해 알아보고, RVO(Reciprocal Velocity Obstacle)를 활용해 동적 장애물 회피 로직을 설계해본다.

공식 문서 : 내비게이션 메시 수정하기

  • 현재 레벨의 상태. 이 상태에서 플레이를 시작하면 캐릭터는 아래처럼 동그라미 표시된 2개의 TargetPoint를 계속해서 왕복한다.

  • 경로탐색 알고리즘으로 현재 위치에서 목표 지점까지의 최소 비용을 계산하여 최단 경로로 이동하는 것이다. 두 지점 사이에 아무것도 없으니 당연히 두 지점을 잇는 직선이 이동 경로가 된다.
  • 이제 레벨에 NavModifierVolume을 배치해보자.
  • 초록색이던 내브메시가 모디파이어 볼륨의 부피만큼 빨간 색으로 변했다. 이 말은 빨간색으로 표시된 부분은 초록색 부분에 비해 비용이 크다는 것이다. 따라서 AI는 가능한 빨간 부분을 피해 이동하려고 한다.

  • 중요한 건 가능한 빨간 부분을 피하려고 하기 때문에, 만약 이동 지점까지 연결된 초록색이 없다면, 빨간 지점으로도 이동한다.


  • 모디파이어 볼륨을 클릭하고, 디테일 패널을 보면 area를 설정할 수 있다. 이미 몇 가지의 프로필이 있는데, 이 프로필에 따라 모디파이어 볼륨의 성질이 달라진다.

사용 가능한 영역 클래스

영역 클래스설명
NavArea_Default볼륨 내 영역과 내비게이션 메시에 기본적으로 동일한 내비게이션 비용을 할당합니다.
NavArea_LowHeight에이전트가 지나가지 못하게 막는 낮은 높이가 있는 이동 조건에 일치하는 영역을 나타냅니다. 내비게이션 메시는 이 볼륨 내에 내비게이션 데이터를 생성하지 않습니다.
NavArea_Null볼륨 내의 빈 영역을 나타냅니다. 내비게이션 메시는 이 볼륨 내에 내비게이션 데이터를 생성하지 않습니다.
NavArea_Obstacle볼륨 내 영역에 높은 내비게이션 비용을 할당합니다.

  • NavArea_Default - 겉보기에 아무런 변화 없음. 경로탐색 알고리즘에 영향도 없다.

  • NavArea_LowHeight - 파란 영역으로 표시. Null과 같이 AI가 지나가지 못하도록 함

  • NavArea_Null - 아예 내브메시가 생성되지 않음.

  • NavArea_Obstacle - 빨간 영역으로 표시. 높은 비용을 설정해서 AI가 피하도록 함.

LowHeight 와 Null의 비교

  • 공통점 : 내비게이션 데이터를 생성하지 않음

  • 차이점
항목NavArea_LowHeightNavArea_Null
의도"여긴 너무 낮아서 못 지나감" 같은 물리적 제약 표현완전히 비워진 영역 (통과 금지 영역 설정)
시각적 표시파란색으로 표시됨회색으로 완전히 비어 보임
자동 생성 조건높이 제한에 의해 NavMesh가 안 만들어질 때 자동 적용됨수동으로 지정해야 함
사용 예시낮은 천장, 작은 구멍 등 벽, 장애물, 금지구역 등AI가 절대 접근하면 안 되는 공간



Reciprocal Velocity Obstacles

Reciprocal Velocity Obstacles(역수 속도 장애물, 이하 RVO) 시스템은 각 에이전트(캐릭터)의 속도 벡터를 계산하여 인근 에이전트와의 콜리전을 피합니다. 이 시스템은 인근 에이전트를 확인하여 에이전트가 계산이 이루어지는 각 시간 단위 내에 일정한 속도로 움직인다고 가정합니다. 선택되는 최적의 속도 벡터는 에이전트의 타깃 방향 선호 속도에 가장 가까운 결과입니다.

언리얼 엔진의 RVO 구현에는 프레임 레이트 종속성을 줄이기 위한 최적화가 포함됩니다. 경로를 지속적으로 다시 계산하지 않기 위한 개선 사항과 잠재적인 콜리전을 해결하기 위한 우선순위 시스템도 포함됩니다. RVO는 회피에 내비게이션 메시를 사용하지 않으므로 어느 캐릭터에서나 내비게이션 시스템과 별도로 사용할 수 있습니다. 이 시스템은 캐릭터 클래스의 캐릭터 무브먼트(Character Movement) 컴포넌트에 포함되어 있습니다.

ㅡ공식 문서 : 내비게이션 시스템으로 회피 사용하기

  • 위 이미지에서 플레이를 누르게 되면, 한 편에 서있는 캐릭터들은 자신의 반대편 타겟포인트로 향하게 된다. 하지만 캐릭터는 12명이고, 이들은 모두 경로탐색 알고리즘에 따라 최단거리·최고효율 경로만 선택할테니, 필연적으로 가운데에서 충돌이 발생하게 된다.


  • 각자 자기가 생각하는 최선의 방향으로만 입력을 하고 있으니 병목현상이 발생한다.
  • 이런 현상을 방지하기 위해 몇 가지의 파라미터 활성화만으로 RVO를 활성화 할 수 있다.

RVO 활성화

GetCharacterMovement()->bUseRVOAvoidance = true;
GetCharacterMovement()->AvoidanceConsiderationRadius = 200.0f;
GetCharacterMovement()->AvoidanceWeight = 0.5f;
  • RVO를 사용하기 위해 필요한 파라미터는 위의 3개이다.

  • 위 공식문서 인용에서 밝혔듯 Character Movement Component에 있어 내비게이션 시스템과 별도 작동.

  • bUseRVOAvoidance - RVO 기능 활성화 플래그.

  • AvoidanceConsiderationRadius - 회피를 시작하는 거리. 위 코드 스니펫에서는 200 uu 이내에 감지되면 회피를 시작한다. 일반적으로 (200-500이 적당)

  • AvoidanceWeight - 회피 행동의 강도. 0.0 ~ 1.0 사이이며 1에 가까울 수록 다른 캐릭터들이 이 캐릭터를 피하고, 0에 가까울 수록 이 캐릭터가 다른 캐릭터를 피한다..고 하는데 실험을 해봤을 때는 크게 차이를 못 느꼈다.


활성화와 비활성화 비교

RVO 비활성화RVO 활성화
  • 활성화를 하면 병목현상이 거의 발생하지 않거나, 발생하더라도 금방 해결된다. 이때 내비게이션 메시를 벗어나는 모습이 보이는 것은 위 인용에 써있듯 RVO는 내비게이션 시스템과 별도로 작동하기 때문이다.


자동 내비게이션 링크 생성

  • 경로탐색 알고리즘을 향상시켜 주는 기능
  • 서로 분리된 내브메시 사이를 자동으로 연결하여, AI 캐릭터가 연결부위를 통해 점프하거나 뛰어내릴 수 있도록 해준다.
  • 원래는 하나하나 생성했어야 하는데, 언리얼 5.5부터 자동 생성이 가능하게 되었다.

RecastNavMesh

  • 월드 아웃라이너에서 recast를 검색하면 RecastNavMesh-default가 보인다.
  • 해당 항목 선택후 디테일 패널에서 Generate Nav Links를 활성화하면 아래와 같이 자동으로 경계마다 화살표가 생긴다. 바로 아래에선 점프 옵션을 조절할 수 있다.


  • 물론 내브메시에 화살표가 생겼다고 바로 점프를 할 수 있는 것은 아니다. 화살표의 역할은 여기서 어떠한 프록시가 가능하다는 표시일 뿐, 어떤 프록시를 수행할 지는 사용자가 직접 설정 해주어야 한다.
  • 새로운 블루프린트 클래스를 만들어, GenerateNavLinksProxy를 선택한다.

  • 위와 같이 코드를 작성한다.

  • 다시 RecastNavMesh-default의 디테일 패널에 들어가 Link Proxy Class에 방금 만든 링크 프록시를 할당해주면, AI 캐릭터가 화살표에 도달하면 제대로 점프하게 된다.
profile
재석로그

0개의 댓글