네비게이션 개요

이 섹션에서는 씬에 NavMesh(네비 메쉬)를 만들고 NavMesh Agent(네비 메쉬 에이전트)와 NavMesh Obstacle(네비 메쉬의 장애물), Off-Mesh Link(오프-메쉬 링크)를 만드는 방법에 대한 자세한 내용을 알려드립니다.






The Navigation System allows you to create characters which can navigate the game world. It gives your characters the ability to understand that they need to take stairs to reach second floor, or to jump to get over a ditch. The Unity NavMesh system consists of the following pieces:

  • NavMesh (short for Navigation Mesh) is a data structure which describes the walkable surfaces of the game world and allows to find path from one walkable location to another in the game world. The data structure is built, or baked, automatically from your level geometry.
  • NavMesh Agent component help you to create characters which avoid each other while moving towards their goal. Agents reason about the game world using the NavMesh and they know how to avoid each other as well as moving obstacles.
  • Off-Mesh Link component allows you to incorporate navigation shortcuts which cannot be represented using a walkable surface. For example, jumping over a ditch or a fence, or opening a door before walking through it, can be all described as Off-mesh links.
  • NavMesh Obstacle component allows you to describe moving obstacles the agents should avoid while navigating the world. A barrel or a crate controlled by the physics system is a good example of an obstacle. While the obstacle is moving the agents do their best to avoid it, but once the obstacle becomes stationary it will carve a hole in the navmesh so that the agents can change their paths to steer around it, or if the stationary obstacle is blocking the path way, the agents can find a different route.



귀찮으니 구글 번역(번역 상태가 살짝 이상하지만 직역?된걸 생각하면서 보면 이해할 수 있을 정도입니다)


네비게이션 시스템을 사용하면 게임 세계를 탐색 할 수있는 캐릭터를 만들 수 있습니다. 그것은 당신의 캐릭터에게 그들이 2 층에 도착하기 위해 계단을 잡거나 도랑을 뛰어 넘기 위해 뛰어 올라야 할 필요가 있음을 이해하는 능력을줍니다. Unity NavMesh 시스템은 다음과 같이 구성됩니다.

  • NavMesh (Navigation Mesh의 약자)는 게임 세계의 걷기 좋은 표면을 설명하고 게임 세계에서 걷기 좋은 곳에서 다른 곳으로가는 길을 찾을 수있는 데이터 구조입니다. 데이터 구조는 레벨 지오메트리에서 자동으로 빌드되거나 구워집니다.
  • NavMesh Agent 구성 요소는 목표를 향해 움직이는 동안 서로를 피하는 문자를 만들 수 있도록 도와줍니다. 요원들은 NavMesh를 사용하여 게임 세계에 대해 논하고 그들은 서로를 피하고 움직이는 장애물을 피하는 방법을 알고 있습니다.
  • Off-Mesh Link 구성 요소를 사용하면 걷기 쉬운 표면을 사용하여 표현할 수없는 탐색 바로 가기를 통합 할 수 있습니다. 예를 들어 도랑이나 담장을 뛰어 넘거나 걸어 가기 전에 문을 여는 것은 모두 오프 메쉬 링크라고 할 수 있습니다.
  • NavMesh 장애물 구성 요소를 사용하면 세계를 탐색하는 동안 에이전트가 피해야하는 움직이는 장애물을 설명 할 수 있습니다. 물리 시스템에 의해 제어되는 배럴 또는 상자는 장애물의 좋은 예입니다. 장애물이 움직이는 동안 요원이 그것을 피하기 위해 최선을 다하고 있지만 일단 장애물이 정지하면 navmesh에 구멍을 뚫어 요원이 경로를 변경하여 주변을 조종하거나 고정 된 장애물로 인해 경로가 차단되는 경우 에이전트는 다른 경로를 찾을 수 있습니다.




우선 네이게이션 만들어보기






네비게이션을 적용할 오브젝트를 모두 선택 합시다.








인스펙터 창에 오른쪽 상단에 보면 Static이라고 있습니다.


그 옆에 세모 단추가 있는데 눌러서 Navigation Static을 눌러줍시다.


※ 구역을 만들기 위해서 지형을 미리 올려두어 계산하게끔 해야되기 때문에 필요한 과정입니다.







유니티 메뉴창 - > Window -> Navigation을 누르시면 오른쪽에 네비게이션 관련 창이 나옵니다.


그 창에 상단을 보시면


Object | Bake | Areas 가 있는데요


Bake를 눌러줍시다. ( 나머지 2개는 신경 안써도 됩니다.)


그러면 이미지와 같은 화면이 나옵니다.




이것이 무엇을 뜻하냐면은


간단히 말해서 '길'로 설정할 범위를 정하라는 겁니다.




Agent Radius: 길로 만들 땅의 반 지름의 크기는 어느정도? ( 값 만큼 외각 여백 결정. )


Agent Height: 어느 높이까지 허용할 거냐? ( 최대 등산 각도. 계단 높이에 영향을 줌 )


Max Slope : 경사는 어느 지점까지 길로 허용할 거냐?


Step Height: : 어느 높이까지 길로 만들거냐? ( 계단 높이. )




모든 셋팅이 다 끝났으면 오른쪽 제일 하단 Bake를 눌러줍시다.






오브젝트 위에 하늘색으로 칠해진곳이 '길'로 허용된 범위 입니다.


캐릭터는 저 범위만 돌아다닐수 있습니다.







플레이어가 될 캐릭터를 맵 맘에 드는곳에 적당히 배치 합니다.







플레이어 캐릭터가 길찾기(Navigation) 수행을 하려면 한 가지 컴포넌트가 필요합니다.


Nav Mesh Agent라는 컴포넌트인데요.




플레이어 캐릭터를 선택한 상태로


유니티 메뉴를 보시면 Component -> Navigation -> Nav Mesh Agent를 누르면


컴포넌트가 하나 추가 됩니다.




터치한 부분까지 캐릭터를 이동시키기 위한 스크립트도 필요한데요.


미리 만들어서 넣어놓읍시다.





컴포넌트의 속성을 보면 여러가지 나와있는데요


Agent Size


- Radius: 충돌 범위( 가로 )


- Height: 충돌 범위( 세로 )


- Base Offset : 기본 출력




Steering


- Speed: 길찾기 이동 수행 스피드 ( 캐릭터 이동 속력 )


- Angular Speed: 회전 스피드 ( 캐릭터 회전 속력 )


- Acceleration: 가속력.


- Stopping Distance: 정지 거리.




※ 캐릭터에 네비 메쉬 에이전트( Nav Mesh Agent) 컴포넌트를 추가하면 기존에 있던


콜라이더(Collider)의 범위는 포함되지 않고, 네비 메쉬 에이전트의 범위로 체크 됩니다.






바로 스크립트를 작성합시다.


설명은 스크립트를 참고합시다.


using UnityEngine;

using System.Collections;

 

public class Nav : MonoBehaviour

{

    public Camera camera;   // 카메라 정보를 얻어오기 위한 변수.

    Animation Ani;          // 애니메이션을 실행 해주기 위한 애니메이션 변수.

    NavMeshAgent Navi;      // 네비게이션을 사용하기 위한 네비게이션 변수.

 

    void Awake()

    {

        Navi = GetComponent<NavMeshAgent>();    // 네비게이션에 대한 컴포넌트를 캐싱

        Ani  = GetComponent<Animation>();       // 애니메이션에 대한 컴포넌트를 캐싱

    }

 

    void Update()

    {

        PlayerTouchMove();  // 화면에 터치 했을 때 이동한다.

    }

 

    void PlayerTouchMove()

    {

        // 매계변수 - 0:왼쪽 1:오른쪽 2:휠

        if (Input.GetMouseButton(0))    // 마우스 왼쪽 버튼을 게속 누르고 있다면.

        {

            Ray ray = camera.ScreenPointToRay(Input.mousePosition);

            // 카메라가 바라보고있는 스크린에서 마우스 위치 정보를 ray에 저장.

            RaycastHit Hit;

            // 충돌에 대한 정보를 저장하기 위한 변수.

 

            // (마우스 위치정보, 충돌에 대하여 값을 담을 변수, 마우스 위치 지점까지 레이저를 얼마만큼의 길이로 쏠것인가?)

            if (Physics.Raycast(ray, out Hit, Mathf.Infinity)) 

            {

                Navi.SetDestination(Hit.point);

                // 매계변수의 위치까지 이동 시켜준다.

            }

        }

 

        // 네비게이션의 목표지점과 현재 캐릭터의 위치가 같으면 함수를 빠져나간다.

        // 쓸때없는 연산을 줄이기 위하여 사용.

        if (transform.position == Navi.destination) return;

        

        // 네비게이션 목표지점과 현재 캐릭터의 위치 사이의 거리를 구한다.

        float dis = Vector3.Distance(Navi.destination, transform.position);

 

        if (dis < 0.1) 

        {

            Ani.CrossFade("Idle");

            transform.position = Navi.destination;

 

            // 목표 지점까지의 거리가 0.1보다 작다면 캐릭터 애니메이션 Idle

            // 캐릭터의 현재 위치를 목표 지점과 완벽하게 일치 시킨다.

        }

        else

            Ani.CrossFade("Run2");

    }

}








Off Mesh Link 만들기






위 그림에서 바닥, 그리고 두 개의 큐브가 있고 이들을 Bake 한 네비게이션 메시들을 볼 수 있다.Off Mesh Link 는 위처럼 떨어져 있는 네비게이션 메시들끼리 연결해주는 개념으로, 두 가지 빙식이 있다.




먼저 첫 번째 방식을 알아보자. 첫 번째 방식은 Bake 시점에 네비게이션 메시들끼리의 높낮이 차이, 떨어진 거리의 차이로부터 연결을 생성하는 방식이다. 높낮이의 경우, 두 네비게이션 메시끼리의 높낮이 차이가 특정 값 이하인 경우 높은 네비게이션 메시에서 낮은 네비게이션 메시로 연결이 생성된다. 이를 직접 눈으로 확인해보자. 왼쪽 큐브를 선택한 후 Navigation Window 에서 다음처럼 설정해준다.






Drop Height 의 경우 상황에 맞게 적당한 값을 넣어준다. 이 상태로 Bake 를 하면 다음과 같은 연결이 생성됨을 확인할 수 있다.




이러한 연결이 생기면 해당 큐브 위의 물체가 바닥의 특정 목표점으로 이동할 수 있는 경로가 만들어진 것이다.




거리의 차이로부터 연결을 생성하는 것은 높낮이 차이의 그것과 크게 다르지 않다. 단지 Drop Height 대신 Jump Distance 가 사용된다는 차이가 있다. 위 상태에서 Jump Distance 에도 적당한 값을 넣어서 Bake 해보면 다음과 같은 결과를 얻을 수 있다.






이번엔 옆 큐브 쪽의 네비게이션 메시로 연결이 생성됐다.



이제 두 번째 방식을 알아보자. 두 번째 방식은 연결되길 원하는 두 지점을 직접 지정하는 방식으로, 컴포넌트를 이용하기 때문에 Bake 할 필요가 없다. 먼저 두 개의 게임 오브젝트를 만들고 연결되길 원하는 각 지점에 배치한다. 이제 또 다른 게임 오브젝트에 Off Mesh Link 컴포넌트를 추가하고 Start, End 에 방금의 오브젝트들을 연결해준다.






두 지점이 네비게이션 메시와 어느 정도 근접해 있어야 연결이 생성된다. 에디터 상에서 두 지점을 이리저리 움직여가며 연결을 만들어보자.





위와 같이 연결을 생성할 수 있다. 두 지점을 변경할 때마다 연결은 새로 갱신된다.







ref : https://docs.unity3d.com/kr/current/Manual/nav-NavigationSystem.html

ref : http://illusionbattle.tistory.com/214

ref : http://cacodemon.tistory.com/entry/Off-Mesh-Link

반응형

+ Recent posts