이황충 2024. 6. 13. 21:07

유니티 게임개발캠프 TIL 38일차

NavMesh의 주요 구성 요소

  1. NavMesh Surface: NavMesh Surface는 NavMesh를 생성할 수 있는 컴포넌트입니다. 이 컴포넌트를 추가하고 빌드하면, 씬의 지형 또는 메시에 따라 NavMesh가 생성됩니다. 일반적으로 바닥이나 플랫폼과 같은 이동 가능한 표면에 할당됩니다.
  2. NavMesh Agent: NavMesh Agent는 NavMesh 위에서 이동할 수 있는 에이전트입니다. 주로 AI 캐릭터에 추가하여 사용하며, 이 컴포넌트는 목적지까지의 경로를 자동으로 계산하고 이동을 처리합니다.
  3. NavMesh Obstacle: NavMesh Obstacle은 NavMesh에 영향을 주는 장애물입니다. 이 컴포넌트를 추가하면 NavMesh가 장애물을 피할 수 있도록 자동으로 업데이트됩니다. 주로 동적인 장애물에 사용됩니다.

NavMesh 활용법

기본 이동 구현:

  • NavMesh Surface를 설정하고 빌드합니다.
  • AI 캐릭터에 NavMesh Agent 컴포넌트를 추가합니다.
  • 스크립트를 통해 목적지 좌표를 설정하면 NavMesh Agent가 자동으로 경로를 계산하고 이동합니다.
using UnityEngine;
using UnityEngine.AI;

public class SimpleMove : MonoBehaviour
{
    public Transform target;

    private NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.SetDestination(target.position);
    }
}

동적 장애물 회피:

  • NavMesh Obstacle 컴포넌트를 사용하여 동적 장애물을 추가합니다.
  • 장애물이 이동하면 NavMesh가 실시간으로 업데이트되어 에이전트가 새로운 경로를 계산합니다.
using UnityEngine;
using UnityEngine.AI;

public class DynamicObstacle : MonoBehaviour
{
    public float speed = 3.0f;
    private Vector3 pointA;
    private Vector3 pointB;

    void Start()
    {
        pointA = transform.position;
        pointB = new Vector3(pointA.x + 5, pointA.y, pointA.z);
    }

    void Update()
    {
        transform.position = Vector3.Lerp(pointA, pointB, Mathf.PingPong(Time.time * speed, 1));
    }
}

 

복잡한 경로 탐색:

  • 여러 목적지를 설정하고 순차적으로 이동하도록 구현할 수 있습니다.
  • 예를 들어, 순찰 경로를 설정하여 AI 캐릭터가 정해진 경로를 순환하도록 합니다.
using UnityEngine;
using UnityEngine.AI;

public class Patrol : MonoBehaviour
{
    public Transform[] points;
    private int destPoint = 0;
    private NavMeshAgent agent;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        agent.autoBraking = false;
        GotoNextPoint();
    }

    void GotoNextPoint()
    {
        if (points.Length == 0)
            return;

        agent.destination = points[destPoint].position;
        destPoint = (destPoint + 1) % points.Length;
    }

    void Update()
    {
        if (!agent.pathPending && agent.remainingDistance < 0.5f)
            GotoNextPoint();
    }
}

 

 

코루틴

 

yield return new WaitForSeconds(float) : 입력한 초(sec) 만큼 대기

yield return new WaitFixedUpdate() : 다음 프레임의 FixedUpdate 까지 대기

yield return WaitUntil(조건) : 조건을 만족할 때까지 대기

yield return startCoroutiune(string) : 입력한 다른 코루틴이 끝날 때까지 대기

yield return new www(string) : 입력한 웹 통신 작업이 끝날 때까지 대기