본문 바로가기
유니티 최고/유니티 구현

[Unity] 유니티 Navigation 시스템을 이용한 클릭 이동 (NavMesh)

by Lee_story_.. 2024. 11. 6.
728x90

 

이번에 만들어볼 기능은

3인칭 RPG에서 많이 사용되는 클릭이동에 대해서 구현해볼 예정입니다. 

 

유니티에서 구현해 놓은  Navigation라이브러리가 있기에,

사용방법만 숙지한다면 구현하는데에는 문제가 없을것으로 보입니다! 

 

 

 

그럼 시작!


 

가장 먼저 AI Navigation을 설치 

(이미 설치되어있을수도 있지만, 없을시에 설치!)

 

 

 

설치하게 되면 

씬 편집창에 아래와 같은 옵션창과 

 

NaviGation에 대한 설정창이 뜨게 됩니다.  

(안뜬다면 >> Window / AI / Navigation 클릭)

 

설정 창에서는 기본적으로 Agent와 Areas에 대해서 설정할 수 있습니다. 

Agent란 네비를 적용시킬 오브젝트에 대한 설정을 하는 창이라고 보시면 될 것 같습니다. 

 

오브젝트의 높이와 너비,

그리고 얼마 정도의 높이는(계단처럼) 올라갈 수 있는지,

또 경사면에 대한 각까지 설정 할 수 있습니다. 

 

실제로 오브젝트를 변환시키는게 아닌, NaviMap을 굽는 과정에서 위와 같은 설정 값들을 고려하여 맵을 만들어 줍니다.

 

 

 

그리고  Areas는 맵상의 구역을 나누어 준다고 보면 되는데,

아래처럼 이미 정해져 있는 이름들을 보면, 

걸을수 있는 곳/ 없는곳 / 점프 이렇게 3가지의 맵 분류가 되어있습니다. 

 

이게 단순히 그 구역에서 점프를 해야하는구나? / 그 구역은 지나갈 수 없구나... 와 같이 이해할 수도 있지만,

 

가장 최단 거리로 이동하려면..? 이동거리와 시간상 가장 코스트가 적게 드는 길로 이동해야한다는 점을 생각하고

위의 Cost설정칸들을 보면 어떤 느낌으로 사용할 수 있는지 이해하실 수 있을것 같습니다. 

 

 

 

그럼 이제 실제로 NavMesh를 생성해줍시다. 

하고 시작하려는데... 대부분의 글들에서는 설정창에서 Object를 통해서 메쉬를 생성하더라구요....

 

 

업데이트를 해서 그런지는 몰라도... 저는 Volume을 통해서 생성해주도록 하겠습니다.

(위 방법으로 진행하는 방법을 모르겠네요...)

 

우선 대충 맵을 하나 만들어주고

 

 

 

빈 오브젝트에 Volume을 추가해줍시다. 

 

 

아래처럼 모든 맵을 감싸는 볼륨을 만들어 주었습니다. 

 

 

 

이 상태로 Surface를 생성해주고 

 

 

Agent의 타입과 기본 Area의 상태 그리고 각각의 설정들을 만져주고!

제일 하단에 Bake를 눌러주면!

 

 

오... Nav Mehs Data가 생성되었습니다. 

 

 

 

이제 마지막으로 여기서 이동할 Agent를 생성해줍시다 .

저는 그냥 큐브에 추가해주었습니다!

 

 

 

그리고 클릭하면 그 위치로 이동하게끔 

코드도 구성해주고 Agent에 적용!

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

public class NavTest : MonoBehaviour
{
    public NavMeshAgent agent;  // NavMeshAgent 컴포넌트를 할당
    public GameObject Test;

    private GameObject temp;


    void Update()
    {
        if (Input.GetMouseButtonDown(0))  // 마우스 왼쪽 버튼 클릭 시
        {
            if (temp != null)
            {
                Destroy(temp);
            }


            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                NavMeshHit navHit;
                if (NavMesh.SamplePosition(hit.point, out navHit, 1.0f, NavMesh.AllAreas))
                {
                    // 목적지를 클릭 위치로 설정
                    agent.SetDestination(navHit.position);

                    temp = Instantiate(Test, navHit.position, Quaternion.identity);
                }
            }
        }
    }


}

 

클릭위치를 Raycast로 잡아주고 Agent의 목적지를 설정해주는 간단한 방식!

 

 

 

 

구우욷

 

 

여기까지만 해도 꽤 만족스럽게 사용할 수 있을 것 같습니다. 

 

 

 

 

여기서 추가적으로!

Volume을 2개 배치하여 

 

Area를 구분지어 줄 수 도 있고!

 

 

 

 

 

 

navMesh Link를 통해 길이 이어지지 않은 구역에 대한 길을 임의로 만들어 줄 수 있었습니다. 

 

 

 

 

 

여기까지가 제가 알아본 NavMesh!

업데이트되면서 먼가... 많은게 바꼈나봐요... 많은 내용들을 담고싶었는데, 

확실히 적을수 있는 내용만 추리다 보니까, 양이 적어졌네요...

 

그래도!  간단하게 사용할 만큼은 될것 같아요... 아마?

그럼 이만 글을 마쳐보도록 하겠습니다!  

 

 

 

 

그리고 참고 블로그!

Navigation 버전이 다른지.. 약간 설정값들이 다르긴 했지만,

그래도 이해하는데에는 가장 자세히 써져있어 링크를 남깁니다!

 

[Unity] Navigation - NavMesh, OffMeshLink

유니티에서 최단 거리를 탐색하여 추적할 수 있는 캐릭터를 생성하는데에 사용되는 Navigation에 대해 알아보자. 그 중, 이번 포스팅은 NavMesh 와 OffMeshLink를 중점적으로 알아보고자 한다.  개념

sikpang.tistory.com

 

 

 

 

 

댓글