[24.02.26]Unity - NavMesh

손지·2024년 2월 26일
0

Unity

목록 보기
16/44

NavMesh

저번에 만들어둔 FPS_캐릭터 프리팹 맵, 탑다운 카메라를 빼와주고 캐릭터에 캡슐콜라이더를 넣습니다.

에이스타 알고리즘 (A*)

에이스타 알고리즘 은 주어진 출발 꼭짓점에서 목표 꼭짓점까지 가는 최단 경로를 나타내는 그래프 탐색 알고리즘 중 하나
출처 : 여기

다익스트라 알고리즘

음의 가중치가 없는 그래프의 한 정점(頂點, Vertex)에서 모든 정점까지의 최단거리를 각각 구하는 알고리즘(최단 경로 문제, Shortest Path Problem)이다.

출처 : 여기

빈 프로젝트를 하나 만들고 장애물 이라고 이름을 지정해둡니다.

그리고 여러가지 장애물울 자식에서 생성해줍니다.

그리고 Windows -> Packages 에 들어가서 AI 패키지를 설치해줍니다.

그리고 AI - 네비게이션에 들어가면

단차가 0.75이상, 경사가 45퍼 이상이면 못올라가게 되어있다.


이동 상태에 따라 Cost (비용) 을 정해줄수있다 .

Windows -> Navigation(Obsolete)

오브젝트를 누를때 상태값을 알수가 있다.

업로드중..

그리고 컴포넌트에서 NavMesh Agent 를 넣어줍니다.

움직임, 장애물에 대한 설정 등을 설정할수가 있다.

AgentControler.cs

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

public class AgentController : MonoBehaviour
{
    private NavMeshAgent agent = null;

    private Vector3 destination = Vector3.zero;


    private void Awake()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (RaycastProcess(ref destination))
            {
                agent.SetDestination(destination);
            }
        }
    }

    private bool RaycastProcess(
        ref Vector3 _point)
    {
        //Vector3 mousePos =
        //    Camera.main.ScreenToWorldPoint(
        //        Input.mousePosition);
        //mousePos.z = Camera.main.nearClipPlane;

        //Vector3 dir =
        //    mousePos -
        //    Camera.main.transform.position;
        //dir.Normalize();

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

        //NavMeshHit hit;
        //if (NavMesh.Raycast(
        //    ray.origin, ray.direction * 100f,
        //    out hit,
        //    NavMesh.AllAreas))
        //{
        //    Debug.Log(hit.position);
        //}

        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red);

        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            _point = hit.point;
            return true;
        }

        return false;
    }
    private void AgentRaycast()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if(Physics.Raycast(ray, out hit)) {
            NavMeshHit navHit;
            //if (agent.Raycast(hit.point)) 
        }
    }
}

미션 : 다중 목적지 지정해서 순서대로 전부 찍고 가기

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

public class AgentController : MonoBehaviour
{
    private NavMeshAgent agent = null;
    private Vector3 destination = Vector3.zero;
    private Vector3[] savePoint = new Vector3[100];
    private Transform pointTr = null;
    public int i = 0;
    public bool isMoving = false;
    [SerializeField] private GameObject[] prefabs;
    private List<GameObject> gameObjects = new List<GameObject>();

    private void Awake()
    {
        agent = GetComponent<NavMeshAgent>();
        pointTr = GameObject.FindGameObjectWithTag("PickingPoint").transform;
    }
    private void Update()
    {
        if (Input.GetKey(KeyCode.LeftShift))
        {
            if (Input.GetMouseButtonDown(0))
            {
                i++;
                if (RaycastProcess(ref savePoint[i]))
                {
                    // 새로운 위치를 저장
                    int selection = Random.Range(0, prefabs.Length);
                    GameObject selectedPrefab = prefabs[selection];
                    Vector3 spawnPos = savePoint[i];
                    GameObject instance = Instantiate(selectedPrefab, spawnPos, Quaternion.identity);
                    gameObjects.Add(instance);
                }
            }
        }

        // 에이전트 이동 체크
        if (!isMoving && i > 0)
        {
            isMoving = true; // 이동 중 플래그 설정
            agent.SetDestination(savePoint[i]); // 다음 포인트로 이동
        }

        // 에이전트 이동이 완료되면
        if (isMoving && !agent.pathPending && agent.remainingDistance <= agent.stoppingDistance)
        {
            isMoving = false; // 이동 완료 후 플래그 해제
            i--; // 다음 포인트로 이동
        }


    }

    private bool RaycastProcess(ref Vector3 _point)
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            _point = hit.point;
            savePoint[i] = hit.point;
            return true;
        }

        return false;
    }
    private void AgentRaycast()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if(Physics.Raycast(ray, out hit)) {
            NavMeshHit navHit;
        }
    }
    private void SetPointPosition(Vector3 _pos)
    {
        pointTr.position = _pos;
    }
}

이렇게하면 가능하긴하다.

profile
게임 개발자가 될사람

0개의 댓글

관련 채용 정보