저번에 만들어둔 FPS_캐릭터 프리팹 맵, 탑다운 카메라를 빼와주고 캐릭터에 캡슐콜라이더를 넣습니다.
에이스타 알고리즘 은 주어진 출발 꼭짓점에서 목표 꼭짓점까지 가는 최단 경로를 나타내는 그래프 탐색 알고리즘 중 하나
출처 : 여기
음의 가중치가 없는 그래프의 한 정점(頂點, 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;
}
}
이렇게하면 가능하긴하다.