본문 바로가기
C#

[C#][Unity] 내비게이션 시스템 (2) 동적 NavMeshLink 생성

by teamnova 2023. 8. 3.
728x90

[C#][Unity] 내비게이션 시스템 (1) 을 보지 않으신 분이면 아래의 링크를 클릭하여 보고 와주시길 바랍니다.

https://stickode.tistory.com/870

 

 

오늘은 NavMeshLink 를 Unity 런타임중에 생성해보겠습니다.

NavMeshLink란?

Unity NavMeshLink는 Unity의 내비게이션 시스템(Navigation System)에서 사용되는 컴포넌트 중 하나로 NavMesh 상에서 경로를 지정하는 데 사용하거나 NavMeshLink 의 두개의 점 시작점과 끝점을 통하여 NavMesh 와 NavMesh 사이의 연결 된 길을 생성하는데 사용 합니다.

오늘은 NavMeshLink 를 Unity 런타임 중에 생성하여 끊어져 있는 길을 이동할 수 있는 예제를 만들어 보겠습니다 

더 자세한 설명은 아래의 설명에서 확인해주세요!

https://docs.unity3d.com/560/Documentation/Manual/class-NavMeshLink.html

 

Unity - Manual: NavMesh Link

NavMesh building components API NavMesh Link The NavMesh Link component is not in the Unity standard install; see documentation on high-level NavMesh building components for information on how to access it. NavMesh Link creates a navigable link between two

docs.unity3d.com

 

NavMeshLink 를 사용하기 위해서 아래링크를 클릭하여 라이브러리를 다운로드 받아주세요

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

 

다운로드 받으신 후 압축을 풀고  파일에 들어가서 Assets 에 있는 NavMeshComponents 를 유니티 프로젝트 Assets 으로 드래그하여 넣어주세요 

NavMeshLInk를 사용하기 이전에 저번시간에 만들었던 장애물을 다 지우고 Plane으로 캐릭터가 건널수 없는 지형을 만들어보겠습니다.

아래와 같이 캐릭터가 움직일 수 있는 지형과 구분지을 수 있도록 색을 변경하고 Navigation 에서 Navigation Area를 Not Walkable 로 설정하고 Navigation Static 을 활성화 한 후 배이크에 들어가 Bake 를 눌러주세요

이렇게 만든 후에 Unit를 실행한다면

 

보시는 것과 같이 건너지 못하는 것을 확인할 수 있습니다.

이제 어떤 아이템을 먹는다면 NavMeshLink 를 생성하여 강을 건널 수 있도록 만들어볼께요

 

먼저 아이템을 생성해보겠습니다.

저는 Point GameObject 를 복사 붙여넣어 만들었습니다.

그리고 Inspector 하단에 있는 Add Componet 를 눌러 Rigidbody를 추가해주시고 Use Gravity 를 해제해주세요.

그리고 Box Collider 에 있는 is Trigger를 체크해주세요

그리고 Caplusle 게임오브젝트도 Rigidbody를 추가해주세요 

다음으로 Hierachy 에 있는 빈공간 우클릭 후 빈 게임오브젝트를 만들어 주겠습니다. 이름은 MakeLink로 하겠습니다.

 

그리고 생성한 빈 게임오브젝트를 아이템이 있는 곳으로 옮겨주세요

MakeLink를 클릭한 후 AddComponent를 클릭하고 NavMeshLink 를 클릭해주세요

그러면 이렇게 Link 가 생기는 것을 볼 수 있습니다.

링크의 위치는 링크 양 끝에 네모난 포인트를 클릭하시면 

이런식으로 링크의 위치를 설정할 수 있게됩니다 저는 링크를 이런식으로 배치해봤습니다.

MakeLink 게임오브젝트에 NavMeshLink 에 있는 Auto Update Position 을 체크해주고맨 위에 있는  체크박스는 해제해주세요!

그리고 아이템에 스크립트를 넣겠습니다 아이템 게임오브젝트 클릭 >  Add Component > new Script  이름은 MakeLink로 하겠습니다.

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

public class MakeLink : MonoBehaviour
{
    // 링크를 만들었던 빈 게임오브젝트를 불러옵니다.
    public GameObject makeLink;

    void OnTriggerEnter(Collider other) {
        // 접족한 Collider 의 태그를 검사합니다.
        if(other.tag == "Player"){
        //빈 게임 오브젝트 Active 열어줍니다.
        makeLink.SetActive(true);
        // 아이템은 사라집니다.
        Destroy(gameObject);
        }
    }
}

그리고 캡슐을 클릭한 뒤에 이전에 적었 CapsuleMoveNav 스크립트를 이렇게 수정 해주세요

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 꼭 넣어주세요 !
using UnityEngine.AI;

public class CapsuleMoveNav : MonoBehaviour
{
    // 목표지점
    public GameObject Point;
    // NavMeshAgent 컴포넌트
    private NavMeshAgent agent;
    // 이동 검사 Bool값
    bool GoPoint;
    void Start()
    {
        // start 유니티 생명주기 start 시점 에서 해당 게임오브젝트의 NavMeshAgent 요소를 가져옵니다.
        agent = GetComponent<NavMeshAgent>();
        // 목적지 Point null 체크해줍니다.
        if(Point != null){
            GoPoint = true;
        }
    }
    void Update()
    {
        MovePoint();
    }

    void MovePoint()
    {
        // 게임오브젝트가 null 이 아니라면
        if(GoPoint){
        // NavMeshAgent 의 월드 좌표에서 목적지을 설정합니다.
        agent.SetDestination(Point.transform.position);
        }
    }
    // 접촉 감지 메서드 / 아이템을 먹엇을 때
    private void OnTriggerEnter(Collider other) {
        if(other.tag == "CreateLink"){
            GoPoint = false;
            // Invoke에 대해서 공부해보세요!
            Invoke("GetPoint", 1f);
        }
    }
    // Invoke로 1초뒤에 실행하는 함수.
    void GetPoint(){
        // Point가 사라지기 때문에 다시 Point를 찾아서 할당해줍니다.
        Point = GameObject.FindWithTag("Point");
        // 할당한 뒤 다시 이동하게 만들어줍니다.
        GoPoint = true;
    }
}

자 그리고 게임오브젝트에게 Tag 를 달아보겠습니다. 

간단히 Tag에 대해서 설명하자면 게임오브젝트의 이름이라기 보단 대명사를 달아준다고 생각하면 될거같습니다.

한번 읽어보세요

https://docs.unity3d.com/Manual/Tags.html 

 

Unity - Manual: Tags

Tags A tag is a reference word which you can assign to one or more GameObjectsThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components

docs.unity3d.com

저는 Capsule 에는 Player Tag를 달아줬습니다.

그리고 아이템에는 CreateLink 테그를 달아줬습니다. 링크를 추가하실때는 아레에 Add Tag... 을 눌러주세요

그리고 마지막 목적지는 Point 라고 달았습니다.

결과입니다.

왼쪽에 씬회면으로 보시면 동적으로 Link 가 생성되어 건너가는 것을 볼 수 있습니다.