Unity

[Unity][2D] 타일에서 셀 단위 이동하기

goliot 2024. 6. 26. 00:47
반응형

타일 셀 단위 이동

  • 바람의 나라나, 포켓몬처럼 버튼을 잠깐 클릭만 해도, 셀에서 한 칸만큼 움직이고 싶을 때가 있다.
  • 우선 방향을 담을 Enum을 준비한다.
public enum MoveDir
{
    None,
    Up,
    Down,
    Left,
    Right,
}
  • Update에서 세 가지 함수를 호출해보자.
    • 입력에 따라 방향을 설정해주는 함수
    • 반드시 한 칸을 움직이게 하는 함수
    • 셀 기준 좌표를 움직이게 하는 함수

 기본 셋팅

public class PlayerController : MonoBehaviour
{
    public Grid _grid;
    public float _speed = 5.0f;

    Vector3Int _cellPos = Vector3Int.zero; // 자신의 셀 위치
    bool _isMoving = false;

    MoveDir _dir = MoveDir.Down;

    void Start()
    {
        Vector3 pos = _grid.CellToWorld(_cellPos) + new Vector3(0.5f, 0.5f);
        transform.position = pos;
    }

    void Update()
    {
        GetDirInput();
        UpdatePosition();
        UpdateIsMoving();
    }
}

1) 입력 받고 방향 설정

void GetDirInput()
{
    if (Input.GetKey(KeyCode.W))
    {
        _dir = MoveDir.Up;
    }
    else if (Input.GetKey(KeyCode.S))
    {
        _dir = MoveDir.Down;
    }
    else if (Input.GetKey(KeyCode.A))
    {
        _dir = MoveDir.Left;
    }
    else if (Input.GetKey(KeyCode.D))
    {
        _dir = MoveDir.Right;
    }
    else
    {
        _dir = MoveDir.None;
    }
}

2) 한 칸 단위의 움직임

void UpdatePosition()
{
    if (_isMoving == false)
        return;

    Vector3 destPos = _grid.CellToWorld(_cellPos) + new Vector3(0.5f, 0.5f);
    Vector3 moveDir = destPos - transform.position;

    // 도착 여부 체크
    float dist = moveDir.magnitude;
    if(dist < _speed * Time.deltaTime)
    {
        transform.position = destPos;
        _isMoving = false;
    }
    else
    {
        transform.position += moveDir.normalized * _speed * Time.deltaTime;
        _isMoving = true;
    }
}

3) 셀 좌표 변경

void UpdateIsMoving()
{
    if (_isMoving == false)
    {
        switch (_dir)
        {
            case MoveDir.Up:
                _cellPos += Vector3Int.up;
                _isMoving = true;
                break;
            case MoveDir.Down:
                _cellPos += Vector3Int.down;
                _isMoving = true;
                break;
            case MoveDir.Left:
                _cellPos += Vector3Int.left;
                _isMoving = true;
                break;
            case MoveDir.Right:
                _cellPos += Vector3Int.right;
                _isMoving = true;
                break;
        }
    }
}

정리

  • 정리하자면, _isMoving을 통해, 다음 셀로 이동중인 상태라면, 다른 움직임을 하지 못하도록 강제한다.
  • float dist = moveDir.magnitude; 를 통해, 도착 여부를 판정하고, 다른 동작 가능 여부를 조정한다.
  • 도착해서 _isMoving이 false가 되면, 자신의 좌표를 셀 기준의 좌표로 변경하고 저장한다.
반응형