❗아래 내용은 해당 기능을 구현하기 위한 최선의 방법이 아닐 수 있음❗
🖋️ 구현 내용
- 클릭 위치로 자동 이동
- 이동 경로에 따라 애니메이션 재생
- 이동 도중 경로 변경시 변경된 경로로 이동
_mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
...
Vector3Int mousePos = mapGrid.WorldToCell(_mousePos);
클릭 위치를 world 좌표로 변환한 뒤 cell 좌표로 변경.
Vector3Int playerPos = Vector3Int.RoundToInt(_playerPos);
다만, 시작좌표(현재 플레이어의 위치)는 WorldToCell() 이 아닌 RoundToInt() 함수를 사용했다.
타일맵의 pivot을 bottomLeft로 사용중이어서 그런지 cell의 왼쪽 아래를 클릭했을 때와 오른쪽 위를 클릭했을 때의 좌표값이 다르게 나왔다.
여러 변환 함수를 사용해 봤을 때 RoundToInt() 값이 가장 오차가 적어 해당 함수를 사용했다.
(Player가 부모 오브젝트 없이 월드 좌표계를 사용하고 있기 때문에 가능했을 것 같다)
경로를 따라 순차적으로 이동해야 했기 때문에 코루틴을 사용했다.
IEnumerator ExSetAutoMove(List<Node> paths)
{
foreach (Node node in paths)
{
Vector3 destPos = new Vector3(node.x, node.y);
moveDir = (destPos - transform.position).normalized;
yield return new WaitUntil(() => Mathf.Abs((destPos - transform.position).magnitude) < 0.1f);
}
moveDir = Vector3.zero;
}
현재 위치 → 다음 위치로 이동하는 벡터의 normalized 값을 구해 이동의 Input 값으로 사용했다.
코루틴의 return 조건은 목적지와 캐릭터의 위치 사이 거리가 0.1 보다 작은 경우로 설정했다.
이 경우 다음 목적지로 넘어간다.
기존에는 키 입력을 받아 이동했기 때문에 아래 코드를 사용하고 있었다.
float x = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
로그를 찍어보니 0~1 사이에서 왔다갔다 하는 값이기에 해당 값을 위에서 구한 normalized 벡터 값으로 대체해서 사용하기로 했다.
float x = moveDir.x;
float y = moveDir.y;
m_animator.SetBool("IsWalkRight", x > 0 && Mathf.Abs(x) >= Mathf.Abs(y));
m_animator.SetBool("IsWalkLeft", x < 0 && Mathf.Abs(x) >= Mathf.Abs(y));
m_animator.SetBool("IsWalkDown", y < 0 && Mathf.Abs(y) > Mathf.Abs(x));
m_animator.SetBool("IsWalkUp", y > 0 && Mathf.Abs(y) > Mathf.Abs(x));
Vector3 velo = new Vector3(x, y, 0) * m_speed * m_deltaTime;
transform.position += velo;
이렇게 바꿔주니 잘 움직였다.
public void SetAutoMove(List<Node> paths)
{
StopAllCoroutines();
StartCoroutine(ExSetAutoMove(paths));
}
코루틴을 사용했기 때문에 단순하게 stop 시키고 다시 세팅했다.
📝 다음에 할 일
대각선 이동 구현실제 캐릭터 이동- 맵 정보 저장 개선