[언리얼엔진] 3D NavMesh (Flying Navigation System)

2025. 6. 5. 20:01·언리얼 엔진/트러블슈팅

1. 개요

언리얼엔진으로 수중환경에서 돌아다니는 AI를 구현해야 하는 상황이었다. 언리얼엔진은 2D NavMesh만 지원하는데 3D NavMesh를 대체 어떻게 구현해야 하는지 자료조사를 해봤지만, 역시나 도움이 될만한 정보는 없었다. Fab에서 판매하는 **Flying Navigation System** 플러그인을 활용하면 3D NavMesh 환경을 구현할 수 있었지만, 플러그인 내에서 제공하는 MoveTo는 형편 없었다. 장애물 인식을 하긴 하는데 정밀하지 못했고, 벽에 끼어 못 움직이는 상황이 태반이었다.


2. 문제 상황

우선 수중생물을 구현하고자 **Death In The Water 2** 스팀 게임을 참고했다. 

 

 

(1) Character Movement 감속 / 가속

상어의 움직임을 분석해보면 우선 감속과 가속을 활용하여 이동하는 것을 볼 수 있다. 일반적으로 Idle 상태에서는 느린 속도로 이동을 하다가 공격을 받거나 플레이어에게 공격을 하러 다가올 때는 보다 빠른 속도로 이동한다. 이때 감속과 가속이 활용된다.

 

언리얼엔진내의 Character Movement Component 에서 감속과 가속 옵션을 제공해주지만, 수중생물의 느낌보다는 사람이 빠르게 달리다가 멈출 때 혹은 회전할 때 감속하는 느낌이었다. 이 느낌이 부자연스럽게 다가오긴 했지만, 본질적인 문제는 또 있었다. 플레이어를 빠르게 추격하며 다가올 때 플레이어가 방향을 틀어버리면 AI 또한 방향을 틀며 이동을 하는데 이때 감속이 발생한다.

 

이때 발생한 감속으로인해 AI는 의도치 않은 움직임을 출력하게 되고, 이때 벽 혹은 NavMesh의 경계면에 낑겨버리는 현상이 발생한다. 물론 이런 문제 상황이 발생했을 때 가장 가까운 NavMesh 지점으로 SetActorLocation을 하면 쉽게 해결이 되겠지만, 플레이어 입장에서는 몰입도의 측면에서 다소 달갑지 않은 상황일 것이다.

 

(2) Execute Task / TickTask

언리얼엔진으로 AI좀 구현해본 사람들은 알 것이다. BTTask 내부적으로 **Execute Task**와 **TickTask**가 구현이 되어있는데, 간단하게 보면 Execute Task는 1회성 호출이고 TickTask는 Tick마다 호출되는 함수라고 생각하면 된다.

Flying Navigation System 플러그인에서 제공하는 MoveTo를 Execute Task에서 호출하는가 TickTask에서 호출하는가에 따라서도 큰 차이가 발생한다. Execute Task는 1회성 호출이므로 경로를 한 번 지정하고나면 그 경로가 잘못된 경로인지 인식을 하지 못 했다.

 

플레이어가 NavMesh 바깥으로 이동하는 상황이다. 하지만 AI는 플레이어가 바깥으로 나갔음에도 아직 플레이어를 쫓아갈 수 있을 것이라 희망을 품으며 벽에 붙어 움직이지 않는 모습을 볼 수 있다. 물론 최대의 Chasing 시간을 둠으로써 다른 이동경로로 교정하긴 하지만, 역시나 부자연스럽다.

 

그렇다면 TickTask를 사용하면 될 것 같지만, TickTask도 나름대로 문제가 있었다. Tick마다 MoveTo를 호출하면 매 틱마다 경로를 생성하기 때문에 플레이어가 NavMesh 바깥으로 이동하는 순간을 포착할 수 있다. 하지만 매 Tick마다 경로를 생성하면 해당 경로가 올바른 경로인지 제대로 검사하지 못 한다. 때문에 다음과 같은 상황이 발생한다.

 

매 Tick마다 경로를 생성하기때문에 움직임은 굉장히 자연스럽지만, 벽에 끼어버렸다.


3. 결론

Flying Navigation System에서 제공해주는 MoveTo는 장애물이 여럿 배치되어 있는 상황에서는 유용하게 활용할 수 없다. 하지만 3D 환경을 인식하여 AI의 이동반경을 생성해주는 기능은 쓸만하다.

결론적으로 나는 Flying Navigation의 MoveTo를 대체할만한 기능을 자체적으로 구현하기로 했다.

'언리얼 엔진 > 트러블슈팅' 카테고리의 다른 글

[언리얼엔진] enum타입 TArray  (1) 2025.08.01
[언리얼엔진] C++ 파일 경로 문제  (0) 2025.06.18
[언리얼엔진] Behavior Tree 인스턴스  (1) 2025.05.28
[언리얼엔진] ApplyPointDamage  (0) 2025.05.20
[언리얼엔진] Simulate Physics + Physics Asset  (0) 2025.05.20
'언리얼 엔진/트러블슈팅' 카테고리의 다른 글
  • [언리얼엔진] enum타입 TArray
  • [언리얼엔진] C++ 파일 경로 문제
  • [언리얼엔진] Behavior Tree 인스턴스
  • [언리얼엔진] ApplyPointDamage
Meoyoung's Development Logs
Meoyoung's Development Logs
내가 보려고 만든 블로그
  • Meoyoung's Development Logs
    이게뭐영
    Meoyoung's Development Logs
  • 전체
    오늘
    어제
    • 분류 전체보기 (229)
      • 게임잼 (3)
      • 언리얼 엔진 (53)
        • 꿀 Tip ! (7)
        • 트러블슈팅 (24)
        • 최적화 (0)
        • 캐릭터 (2)
        • VR (1)
        • Lighting (2)
        • 멀티스레드 (2)
        • 문자열 (0)
      • C++ (31)
        • 문법 정리 (8)
        • [서적] Fundamental C++ 프로그래밍 .. (5)
        • [서적] 이것이 C++이다 (11)
        • [서적] Effective C++ (7)
      • C# (1)
        • [서적] 이것이 C#이다 (1)
      • 코딩테스트 (26)
        • 프로그래머스 (6)
        • 알고리듬 (13)
        • 자료구조 (7)
      • 컴퓨터 과학 (27)
        • 운영체제 (11)
        • 데이터베이스 (0)
        • 디자인패턴 (0)
        • 자료구조 (5)
        • 네트워크 (0)
        • 컴퓨터구조 (11)
      • 면접준비 (0)
        • C++ (0)
        • 운영체제 (0)
        • 자료구조 (0)
      • 프로젝트 (25)
        • [팀프로젝트] The Fourth Descenda.. (5)
        • [개인프로젝트] FPS 구현 맛보기 (5)
        • GetOutOf (15)
      • 기타 (54)
        • [강의] 이득우의 언리얼 프로그래밍 Part1 (10)
        • [강의] 이득우의 언리얼 프로그래밍 Part3 (12)
        • [강의] 소울라이크 개발 A-Z (4)
        • [강의] Udemy-2D (5)
        • [서적] 인생 언리얼5 (4)
        • 스파르타코딩클럽 (15)
        • 객체지향프로그래밍 (2)
        • 컴퓨터회로 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    쉘정렬
    경북게임잼
    선택정렬
    삽입정렬
    자료구조
    버블정렬
    알고리즘
    게임개발
    게임잼
    셸정렬
    참가후기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Meoyoung's Development Logs
[언리얼엔진] 3D NavMesh (Flying Navigation System)
상단으로

티스토리툴바