개발 관련/SW, App 관련

Unity의 Nav Mesh 알아보기

by 소서리스25 2023. 5. 2.
반응형

Unity의 Nav Mesh 알아보기

 

이번에는 몬스터에게 가장 많이 사용되는 기능 중에 하나인 Nav Mesh에 대해서 알아본다.

개발했던 탑다운 게임 앱에서 유용하게 활용한 Unity의 기능으로 기본적으로 제공하고 있다.

 

먼저 다음과 같이 오브젝트들을 배치한다.

Nav Mesh를 적용하기 위한 오브젝트들의 기본 배치
Nav Mesh를 적용하기 위한 오브젝트들의 기본 배치

큐브들은 장애물이 될 것이도 캡슐은 플레이어라고 보면 된다.

 

다음으로 메뉴에서 Windows > AI > Navigation을 선택해 준다.

그러면 Inspector 탭 옆에 Navigation 탭이 새로 나타난다. Objecr 옆으로 Agent, Areas, Bake가 있으며, 

기본적인 선택은 Object로 Scene Filter로  All 선택되어 있을 것이다. 전체에서 필요한 것으로 할 것이므로

Mesh Renderers나 Terrains는 현재로서는 선택할 필요가. 없다.

 

다음으로 옆의 Bake를 선택해 보면 다음과 같다.

Navigation의 Bake 선택시 나타난 화면
Navigation의 Bake 선택시 나타난 화면

 

Bake를 선택하면 위와 같은 화면이 나타나는데 Learn... workflow.를 클릭하면 깃허브로 연결되어

Nav Mesh의 Component에 대한 내용을 샘플로 확인할 수 있다.

Bake의 상세 내용은 해당 그림으로도 설명이 잘 되어 있다.

Bake를 눌러 보자.. 그러나 현재는 아무 반응이 없을 것이다. 이유는 Nav Mesh를 적용할 오브젝트를

정해 주어야 한다. 

 

현재 오브젝트들은 움직이지 않을 것이므로 해당 객체를 모두 선택해 주고 Inspector에서 Static을 확장하여

Navigation Static을 체크해 주자.(움직이는 오브젝트의 경우에는 해당 오브젝트의 Static 설정을 하면 안되며, Component에 Nav Mesh Opstacle을 설정해 줘야 한다.)

 

다시 Bake를 클릭하면 다음과 같이 영역이 설정된 것을 볼 수 있다.

오브젝트 선택에 따른 Navi Mesh 영역 Bake
오브젝트 선택에 따른 Navi Mesh 영역 Bake

 

푸른 지역이 이동 가능한 영역임을 알 수 있다.

이 부분과 관련된 것은 Areas에서 추가적으로 확인이 가능하다. Cost를 통해 이동의 소요비용을

설정할 수 있다.

Cost가 클 수록 이동의 우선순위가 낮아진다. 만약 막힌 길의 비용이 낮지만 갈 수 없다면  비용이 크더라도

그 지역을 지나갈 수 있다. 이러한 부분을 설정할 수 있다.

Areas에서 cost를 통해 이동의 우선 순위를 정할 수 있다.
Areas에서 cost를 통해 이동의 우선 순위를 정하기

 

아무튼 가장 많이 설정을 바꾸는 것은 Agent Radius일 것이다. 아래와 같이 수치를 낮추면 이동가능

영역이 축소된다.

Agent Radius 값으로 이동가능 영역을 조절 할 수 있다.
Agent Radius 값으로 이동가능 영역을 조절 할 수 있다.

 

다음은 Agents 부분으로 이는 플레이어가 이동하는 것이라 보면 되고 이를 위한 설정이라고 보면 된다.

위에서 만들어진 캡슐이 플레이어 역할이다.

캡슐이 플레이어 역할을 하므로 Component에 Nav Mesh Agent를 추가하면 다음과 같이 기본 옵션들이

나타난다.

플레이어에 Nave Mesh Agent를 추가한다.
플레이어에 Nave Mesh Agent를 추가한다.

 

추가하면 여러가지 옵션들이 나타나는데 이 인스펙터에서 조절해 줘도 되고, 스크립트에서 연결하여

사용할 수도 있다.

그리고 다음과 같은 스크립트를 플레이어에 적용하여 준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using System.Collections;
using UnityEngine;
using UnityEngine.AI;

public class Player : MonoBehaviour
{
    public GameObject _camera;
    
    NavMeshAgent _pathFinder;
    Vector3 _targetPosition;
 
    RaycastHit _hit;
    Ray _ray;
    
    bool _playerMoveState = false;
    bool _playerState = true;

    void Start()
    {
        _pathFinder = GetComponent<NavMeshAgent>();
       StartCoroutine(UpdatePath());
    }

    void Update()
    {
        if (Input.GetMouseButtonUp(1))
        {
            _ray = Camera.main.ScreenPointToRay(Input.mousePosition);

            if (Physics.Raycast(_ray, out _hit, 100))
            {
                _targetPosition = _hit.point;
                _playerMoveState = true;
            }
        }
    }

   IEnumerator UpdatePath()
  {
        float _refreshRate = 0.5f;

        while (_playerState)
        {
            if (_playerMoveState)
            {
                _pathFinder.SetDestination(_targetPosition);

                if (Vector3.Distance(transform.position, _targetPosition) < 0.1f)
                    _playerMoveState = false;
            }

            yield return new WaitForSeconds(_refreshRate);
        }
    }
}
 
cs

 

이 스크립트는 마우스 우측버튼으로 바닥을 찍으면 해당 위치로 플레이어가 이동한다. 이때 다음의 영상에서

보시는 바와 같이 장애물을 피해서 간다.

나머지 옵션값들 조정하면 세부적으로 이동속도, 가속도, 정확도 등을 조절 할 수 있다.

Nav Mesh Agent 설정결과 플레이 동영상

 

 

반응형

댓글