깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)
Unity 전체 링크
이전 글에서 네비메쉬를 이용하여 Bake로 맵을 구우면 Player가 장애물을 쉽게 피하면서 움직일 수 있었다.
이제 라인 렌더러를 이용하여 Player가 이동하는 경로 그리기를 해보자.
아래와 같이 PathFinder.cs를 수정한다.
goTarget은 삭제하고 makePath로 함수 이름을 변경하였다. (TargetChanger.cs의 goTarget 함수도 이름을 변경)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class PathFinder : MonoBehaviour
{
public GameObject target;
NavMeshAgent agent;
LineRenderer lr;
void Start()
{
agent = this.GetComponent<NavMeshAgent>();
lr = this.GetComponent<LineRenderer>();
lr.startWidth = lr.endWidth = 0.1f;
lr.material.color = Color.blue;
lr.enabled = false;
}
public void makePath()
{
lr.enabled = true;
StartCoroutine(makePathCoroutine());
}
IEnumerator makePathCoroutine()
{
agent.SetDestination(target.transform.position);
lr.SetPosition(0, this.transform.position);
yield return new WaitForSeconds(0.1f);
drawPath();
}
void drawPath()
{
int length = agent.path.corners.Length;
lr.positionCount = length;
for (int i = 1; i < length; i++)
lr.SetPosition(i, agent.path.corners[i]);
}
}
Start에서는 LineRenderer의 설정을 초기화한다.
LineRenderer lr;
void Start()
{
agent = this.GetComponent<NavMeshAgent>();
lr = this.GetComponent<LineRenderer>();
lr.startWidth = lr.endWidth = 0.1f;
lr.material.color = Color.blue;
lr.enabled = false;
}
agent의 path.corners에 agent가 이동할 경로가 Vector3[]로 저장되어 있다.
따라서 LineRenderer의 SetPosition으로 경로를 그릴 수 있다.
void drawPath()
{
int length = agent.path.corners.Length;
lr.positionCount = length;
for (int i = 1; i < length; i++)
lr.SetPosition(i, agent.path.corners[i]);
}
agent가 SetDestination을 호출하자마자 drawPath를 하면 정상적으로 경로를 잡지 못하기 때문에
코루틴을 이용하여 딜레이(0.1초)를 준 다음 경로를 그린다.
그 전에 LineRender에 최초 출발점을 Setting 한다.
IEnumerator makePathCoroutine()
{
agent.SetDestination(target.transform.position);
lr.SetPosition(0, this.transform.position);
yield return new WaitForSeconds(0.1f);
drawPath();
}
이제 makePath를 TargetChanger가 호출하면 된다.
public void makePath()
{
lr.enabled = true;
StartCoroutine(makePathCoroutine());
}
Player에 LineRenderer를 추가하고 게임을 실행해보자.
이제 도착점이 바뀔 때마다 경로가 그려진다.
위와 같이 속도가 빠르면 경로를 벗어나기도 하므로, 적절히 NavMeshAgent의 Speed 값을 조절하자.
지나간 경로 삭제하기
위의 경우는 라인 렌더러 경로가 계속 남아 있어서 보기 불편할 수 있다.
따라서 지나간 경로는 사라지게 해보자.
makePathCoroutine을 아래와 같이 수정하자.
현재 위치와 도착점 사이의 거리가 충분히 줄어들 때까지 LineRenderer를 새로 그리면 된다.
IEnumerator makePathCoroutine()
{
agent.SetDestination(target.transform.position);
lr.SetPosition(0, this.transform.position);
while (Vector3.Distance(this.transform.position, target.transform.position) > 0.1f)
{
lr.SetPosition(0, this.transform.position);
drawPath();
yield return null;
}
lr.enabled = false;
}
이제 지나간 경로는 사라지는 것처럼 보이게 된다.
최종 코드는 다음과 같다.
PathFinder.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class PathFinder : MonoBehaviour
{
public GameObject target;
NavMeshAgent agent;
LineRenderer lr;
void Start()
{
agent = this.GetComponent<NavMeshAgent>();
lr = this.GetComponent<LineRenderer>();
lr.startWidth = lr.endWidth = 0.1f;
lr.material.color = Color.blue;
lr.enabled = false;
}
public void makePath()
{
lr.enabled = true;
StartCoroutine(makePathCoroutine());
}
void drawPath()
{
int length = agent.path.corners.Length;
lr.positionCount = length;
for (int i = 1; i < length; i++)
lr.SetPosition(i, agent.path.corners[i]);
}
IEnumerator makePathCoroutine()
{
agent.SetDestination(target.transform.position);
lr.SetPosition(0, this.transform.position);
while (Vector3.Distance(this.transform.position, target.transform.position) > 0.1f)
{
lr.SetPosition(0, this.transform.position);
drawPath();
yield return null;
}
lr.enabled = false;
}
}
TargetChanger.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetChanger : MonoBehaviour
{
RaycastHit hit;
public GameObject player;
void Update()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 100.0f, Color.red);
if (Physics.Raycast(ray, out hit, Mathf.Infinity))
{
this.transform.position = hit.point;
player.GetComponent<PathFinder>().makePath();
}
}
}
}
Unity Plus:
Unity Pro:
Unity 프리미엄 학습:
'개발 > Unity' 카테고리의 다른 글
(1) Project Setting - 유니티 시네머신 튜토리얼 (0) | 2022.09.14 |
---|---|
유니티 - 스포트 라이트가 오브젝트를 관통하는 문제 해결하기 (How to Fix the Spot Light Through the GameObject) (1) | 2022.08.31 |
유니티 - 네비메쉬 에이전트로 장애물 피하면서 이동하기 (0) | 2022.08.25 |
유니티 C# - 하위 폴더의 모든 파일 통합하기 (Recursive Folder Merger) (0) | 2022.08.25 |
유니티 - 윈도우 빌드 해상도, 창모드 설정하기 (0) | 2022.08.24 |
댓글