Version: 2020.1
마우스로 클릭한 포지션으로 에이전트 이동
애니메이션과 내비게이션 연결

포인트 세트 사이에 에이전트 패트롤 생성

많은 게임이 자동으로 영역을 패트롤하는 NPC를 활용하고 있습니다. 이 동작을 실행하는 데 내비게이션 시스템을 사용할 수 있지만 일반적인 경로 탐색보다 더 많은 부분에서 관여해야 합니다. 일반적인 경로 탐색은 두 점 사이에 단순히 가장 가까운 경로를 지정하는 것으로 제한되고 예상되는 패트롤 루트를 만들어 냅니다. NPC가 경로를 따라 움직이고 방문하는 시퀀스를 특정할 때 “유용한” 키 포인트 세트를 지정하여 더 그럴싸한 패트롤 패턴을 만들어 낼 수 있습니다. 예를 들면 미로에서 갈림길과 코너에 키 패트롤 포인트를 지정하고 에이전트가 모든 복도를 체크하도록 할 수 있습니다. 사무실 건물에서는 키 포인트가 개별 사무실이나 다른 방이 될 수 있습니다.

키 패트롤 포인트가 마크된 미로
키 패트롤 포인트가 마크된 미로

이상적인 패트롤 포인트의 시퀀스는 NPC가 어떻게 행동하길 원하는지에 따라 다릅니다. 예를 들어 로봇이 체계적인 순서로 포인트를 방문하지만 인간 경비는 더 랜덤한 패턴으로 플레이어를 잡으려 들지 모릅니다. 로봇의 단순한 동작은 아래의 코드로 구현될 수 있습니다.

패트롤 포인트는 변환의 공용 배열을 사용해서 스크립트에 제공됩니다. 이 배열은 인스펙터에서 게임 오브젝트를 사용하여 포인트의 포지션을 마크하기 위해 할당될 수 있습니다. GotoNextPoint 함수는 에이전트를 위한 목적지 포인트를 지정하며(에이전트를 움직이게 만듦) 다음 호출에 사용할 새로운 목적지를 선택합니다. 이에 따라 코드가 배열에서 발생하는 순서대로 포인트를 돌아다니게 됩니다. 이는 쉽게 수정할 수 있는데, 예를 들어 Random.Range를 사용하여 랜덤하게 배열 인덱스를 고를 수 있습니다.

Update 함수에서 remainingDistance 프로퍼티를 사용하여 에이전트가 얼마나 목적지에서 떨어져 있는지를 스크립트가 체크합니다. 거리가 짧으면 GotoNextPoint 를 호출하여 다음 패트롤을 시작하게 합니다.

    // Patrol.cs
        using UnityEngine;
        using UnityEngine.AI;
        using System.Collections;


        public class Patrol : MonoBehaviour {

            public Transform[] points;
            private int destPoint = 0;
            private NavMeshAgent agent;


            void Start () {
                agent = GetComponent<NavMeshAgent>();

                // Disabling auto-braking allows for continuous movement
                // between points (ie, the agent doesn't slow down as it
                // approaches a destination point).
                agent.autoBraking = false;

                GotoNextPoint();
            }


            void GotoNextPoint() {
                // Returns if no points have been set up
                if (points.Length == 0)
                    return;

                // Set the agent to go to the currently selected destination.
                agent.destination = points[destPoint].position;

                // Choose the next point in the array as the destination,
                // cycling to the start if necessary.
                destPoint = (destPoint + 1) % points.Length;
            }


            void Update () {
                // Choose the next destination point when the agent gets
                // close to the current one.
                if (!agent.pathPending && agent.remainingDistance < 0.5f)
                    GotoNextPoint();
            }
        }
    // Patrol.js
        var points: Transform[];
        var destPoint: int = 0;
        var agent: NavMeshAgent;


        function Start() {
            agent = GetComponent.<NavMeshAgent>();

            // Disabling auto-braking allows for continuous movement
            // between points (ie, the agent doesn't slow down as it
            // approaches a destination point).
            agent.autoBraking = false;

            GotoNextPoint();
        }


        function GotoNextPoint() {
            // Returns if no points have been set up
            if (points.Length == 0)
                return;
            
            // Set the agent to go to the currently selected destination.
            agent.destination = points[destPoint].position;

            // Choose the next point in the array as the destination,
            // cycling to the start if necessary.
            destPoint = (destPoint + 1) % points.Length;
        }


        function Update() {
            // Choose the next destination point when the agent gets
            // close to the current one.
            if (!agent.pathPending && agent.remainingDistance < 0.5f)
                GotoNextPoint();
        }
마우스로 클릭한 포지션으로 에이전트 이동
애니메이션과 내비게이션 연결