LineRenderer로 오브젝트 연결선 구현
Timeline에 Block이 배치될 때 Block끼리 연결해주는 라인을 그린다.
2D라 라인이 안보이는 위치가 있어서 LateUpdate에 카메라 방향을 찾아서 회전시켜 모든 방향에서 라인이 잘 보이도록 했다.
public LineRenderer lineRenderer;
public List<TimelineElement> elements = new();
private void Awake()
{
lineRenderer = GetComponent<LineRenderer>();
TimelineManager.Instance.SetBlockConnector(this);
}
private void LateUpdate()
{
lineRenderer.transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward);
}
public void DrawLines()
{
elements = TimelineManager.Instance.PlacedBlocks;
lineRenderer.positionCount = elements.Count;
for (int i = 0; i < elements.Count; i++)
{
lineRenderer.SetPosition(i, elements[i].transform.position);
}
}
위처럼만 하면 벽을 뚫고도 라인이 만들어질 수 있다.
플레이어가 갈 수 있는 블럭 사이의 최단 경로를 계산하여 라인을 그려야 했다.
NavMesh를 사용하여 최단 경로를 계산할 수 있도록 했다.
public void DrawLines()
{
if(!gameObject.activeSelf) gameObject.SetActive(true);
elements = TimelineManager.Instance.PlacedBlocks;
List<Vector3> fullPathPoints = new();
if (elements.Count == 1) return;
for (int i = 0; i < elements.Count; i++)
{
if (i == elements.Count - 1) break;
Vector3 start = elements[i].transform.position;
Vector3 end = elements[i + 1].transform.position;
NavMeshPath path = new();
if (NavMesh.CalculatePath(start, end, NavMesh.AllAreas, path))
{
fullPathPoints.AddRange(path.corners);
}
else Debug.LogWarning($"[PATH FAIL] from {start} to {end}");
}
if (elements.Count > 0) fullPathPoints.Add(elements[^1].transform.position);
lineRenderer.positionCount = fullPathPoints.Count;
lineRenderer.SetPositions(fullPathPoints.ToArray());
}
NavMesh.CalulatePath를 사용하려면 Block 객체가 NavMesh에 위치해야 했다. 하지만 NavMesh는 바닥에 깔려있어 다른 오브젝트 위에 위치한 Block이 사용하기 어려웠다.
Agent의 max slope와 step height를 높여주어 어느정도 해결했다.
