Unity/정보

[Unity] 고급네비메쉬

달시_Dalsi 2023. 9. 23. 19:46

고급네비메쉬 소개

유니티에서 2022 버전부터 기존 네비메쉬의 단점을 보완한 고급네비메쉬를 제공한다. 

이에 대해 알아보자.

아래 영상을 참고했다.

https://www.youtube.com/watch?v=OIcqe4ad5oA 

 

유니티 패키지 매니저에서 AI 네비게이션을 인스톨하자.

 

유니티 버전이 2022 이상이 아니라면 아래 깃허브에서 고급네비메쉬를 따로 추가해줘야한다.

https://github.com/Unity-Technologies/NavMeshComponents

 

GitHub - Unity-Technologies/NavMeshComponents: High Level API Components for Runtime NavMesh Building

High Level API Components for Runtime NavMesh Building - GitHub - Unity-Technologies/NavMeshComponents: High Level API Components for Runtime NavMesh Building

github.com

 

 


주요 기능

일단 사전 작업으로 사용할 지형 및 캐릭터 역할을 만들고 네비메쉬로 베이크까지 했다.

 

 

1. NavMeshAgent

agnet type을 통해 다른 값을 가진 타입을 생성시킬 수 있다.

나머지 아래 값들은 이름만 봐도 알수있다.

 

 

 

 

2. NavMeshSurface

해당 컴포넌트를 통해 에이전트가 움직일 공간을 베이크할 수 있다.

위에서 에이전트 종류를 2가지로 만들어 각각 베이크해봤다.

에이전트별로 설정된 값이 다르기에 자세히보면 각각 크기가 다르게 베이크된걸 알 수 있다. 

 

3. NavMeshObstacle

장애물로 인식하는 물체에게 달아주는 컴포넌트다.

아래처럼 문 역할을 할 큐브를 추가하여 움직이게 해놓았다.

 

아래처럼 장애물 때문에 길을 건너가지 못한다.

 

 

4. NavMeshLink

원래는 갈수 없는 길을 링크를 통해 길을 만들수 있다.

5. NavMeshModifier & Volume

일정 구역을 다른 Area Type으로 구별하여 베이크하도록 해준다.

아래 영상에선 선택 구역을 water로 설정하고 코스트값을 올려주었고 주변으로 움직여 보았다.

 

지역 코스트값이 5라 돌아가는 모습을 볼 수 있다.

 


동적 베이크

 

NavMeshSurface에서 Collect Objects값을 설정하면 원하는 만큼만 베이크할 수 있다.

이를 이용하여 캐릭터 주위만 동적 베이크를 할 것이다.

 

아래와 같은 스크립트를 이용하여 위의 영상처럼 동적베이크를 만들었다.

using System.Collections;
using System.Collections.Generic;
using Unity.AI.Navigation;
using UnityEngine;
using UnityEngine.AI;

public class ClickMoving : MonoBehaviour
{
    NavMeshAgent agent;

    public Transform movetarget;
    public NavMeshSurface surface;

    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        StartCoroutine(updateNavmesh());
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(1))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if(Physics.Raycast(ray, out RaycastHit hit))
            {
                movetarget.position = hit.point;
                agent.SetDestination(hit.point);
            }
        }

        if(Vector3.Distance(surface.transform.position, transform.position) > 5f)
        {
            surface.transform.position = transform.position;
            surface.BuildNavMesh();
        }
    }

    IEnumerator updateNavmesh()
    {
        while (true)
        {
            surface.transform.position = transform.position;
            surface.BuildNavMesh();

            yield return new WaitForSeconds(1f);
        }
    }
}

 

 


마무리 및 결론

기존의 유니티 네비메쉬의 단점을 보완하고 새로운 기능도 추가되었다고한다.

그중에서도 동적베이크가 가장 인상깊다. 하지만 동적베이크는 비용이 많이 든다고하니 적절한 상황에만 써야할 것 같다.