## 언리얼 엔진 4 ## 커스텀 네비게이션 시스템 박재완 jaewan.huey.park@gmail.com --- ## 목차 - 네비게이션 시스템 개요 - 왜 커스텀이 필요한가? - 커스텀 네비게이션 데이터 구현 맛보기 - 참고자료 - Q & A --- ## 네비게이션 시스템 인공지능 에이전트가 경로 찾기를 사용하여 레벨을 탐색하는 기능을 제공 --- ![](/unreal-engine/custom-navigation-system/level.png) 벽을 피해 목적지로 가고 싶다면? --- ![](/unreal-engine/custom-navigation-system/level-with-navigation.png) 그냥 사용하시면 됩니다 --- ## 왜 커스텀이 필요한가? --- ### 이유 1. 특별한 연출 --- 언리얼 엔진 4 에 내장 네비게이션은 [recastnavigation](https://github.com/recastnavigation/recastnavigation) 기반 --- 일반적인 상황에서 잘 작동하지만 특별한 연출을 보여주기엔 아쉬운 부분들이 있음 --- ### 특별한 연출들의 예 - 높은 지형에서 낮은 지형으로 자유로운 낙하 <!-- .element: class="fragment" --> - 점프 <!-- .element: class="fragment" --> - NPC 들이 경로 가장자리를 따라가는 문제 <!-- .element: class="fragment" --> - 벽타기? <!-- .element: class="fragment" --> --- ### 이유 2. 아쉬운 제어 기능(서버와 공용으로 사용할 때) --- ### 아쉬운 제어 기능 - 옥트리 크기, 위치를 의도한 값으로 설정 <!-- .element: class="fragment" --> - 런타임에 다양한 지형의 변경(하우징 등) <!-- .element: class="fragment" --> --- ### 왜 커스텀이 필요한가? 1. 특별한 연출 2. 아쉬운 제어 기능 --- ## 커스텀 네비게이션 데이터 ## 구현 맛보기 --- ```cpp class NAVIGATIONSYSTEM_API ANavigationData : public AActor, public INavigationDataInterface ``` - 추상화된 네비게이션 데이터 - 네비게이션 시스템에서 사용하는 인터페이스 제공 --- ```cpp class NAVIGATIONSYSTEM_API ARecastNavMesh : public ANavigationData ``` - ARecastNavMesh 는 ANavigationData 를 상속받음 --- ### 주요 자료구조 - NavMesh <!-- .element: class="fragment" --> - 네비게이션 데이터 구현체 - ANavigationData 상속 - NavMeshGenerator <!-- .element: class="fragment" --> - 네비게이션 데이터를 생성하는 생성기 FNavDataGenerator 상속 - NavRenderingComponent <!-- .element: class="fragment" --> - 생성결과를 확인하기 위한 렌더링 컴포넌트 - NavSceneProxy, NavSceneProxyData <!-- .element: class="fragment" --> - 렌더링용 씬 프록시와 데이터 --- ### NavMesh 주요 함수 ```cpp // 생성자 AHueyNavMesh() // 네비게이션 생성기를 생성합니다. virtual void ConditionalConstructGenerator() override; // 렌더링 컴포넌트를 생성합니다. virtual UPrimitiveComponent* ConstructRenderingComponent() override; // 경로를 찾습니다. static FPathFindingResult FindPath( const FNavAgentProperties& agentProperties, const FPathFindingQuery& query); ``` --- ### NavMeshGenerator 주요 함수 ```cpp // 모두 리빌드합니다. virtual bool RebuildAll() override; // 틱마다 비동기 빌드를 시도합니다. virtual void TickAsyncBuild(float DeltaSeconds) override; // 네비게이션 바운드가 변경되었을 때를 처리합니다. virtual void OnNavigationBoundsChanged() override; // 변경된 부분만 리빌드합니다. virtual void RebuildDirtyAreas(const TArray<FNavigationDirtyArea>& DirtyAreas) override; ``` --- ### NavRenderingComponent 주요 함수 ``` cpp // 씬에 표현될 프록시를 만듭니다. virtual FPrimitiveSceneProxy* CreateSceneProxy() override; // 컴포넌트의 영역을 계산합니다. // // 렌더링에 포함할지 판정할 때 사용됩니다. virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override; ``` --- ### NavSceneProxy 주요 함수 ```cpp // ViewRelevance 를 반환합니다. // // ViewRelevance 는 씬에 보일지에 관한 관련성을 표현하는 값입니다. virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override; ``` --- ### 에디터 설정 1. Project Settings 2. Engine - Navigation System 3. Agents 에서 Nav Data Class, Preferred Nav Data --- ### 에디터 설정 ![](/unreal-engine/custom-navigation-system/editor-setting.png) --- ## 더 알아가야 할 부분 - 생성된 네비게이션 데이터 저장은 어디서 하지? ```cpp // 여기일 것 같은 느낌적 느낌 virtual void Serialize( FArchive& Ar ) override; ``` - 변경된 부분만 리빌드 - ~~점프를 이야기하셨던 것 같습니다만...~~ --- ## 참고자료 - [언리얼 엔진 4 커스텀 네비게이션 메쉬 생성기](https://github.com/hueypark/navgen) - [Navigation Mesh Generation(언리얼 엔진 커스텀 네비게이션 메쉬 생성에 관한 문서)](http://javid.nl/Navigation%20Mesh.pdf) - [Study: Navigation Mesh Generation](http://www.critterai.org/projects/nmgen_study/) - [recastnavigation](https://github.com/recastnavigation/recastnavigation) --- ## Q & A