[Unity] 플레이어 이동에 애니메이션 적용

Jihoon·2022년 3월 21일
0

MMO_Unity

목록 보기
5/22

유니티 설정



PlayerController

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

    public class PlayerController : MonoBehaviour
	{
    [SerializeField]
    float _speed = 10.0f;

    Vector3 _destPos;


    void Start()
    {
        Managers.Input.MouseAction -= OnMouseClicked;
        Managers.Input.MouseAction += OnMouseClicked;
        // Action을 두번 구독하는 경우가 생기지 않도록 먼저 구독을 끊고 다시 구독을 한다.
    }

    public enum PlayerState
    {
        Die,
        Moving,
        Idle,
    }

    PlayerState _state = PlayerState.Idle;

    void UpdateMoving()
    {
        Vector3 dir = _destPos - transform.position;
        if (dir.magnitude < 0.0001f)
        {
            _state = PlayerState.Idle;
        } // 목적지까지의 거리가 매우 작다면(도착했다면) 이동중이라는 상태를 false로 만든다.
        else
        {
            float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, dir.magnitude);
            // 목적지 좌표에 도착하고도 계속 rotation을 변경하며 목적지에 가려는 상황을 없애기 위해 
            // 목적지 까지의 거리보다 속도가 높아지면 속도를 0으로 만든다.
            transform.position += dir.normalized * moveDist;
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime);
        }

        // 애니메이션 처리
        Animator anim = GetComponent<Animator>();
        // 현재 게임 상태에 대한 정보를 넘겨준다.
        anim.SetFloat("speed", _speed);
    }

    void UpdateIdle()
    {
        // 애니메이션
        Animator anim = GetComponent<Animator>();
        // 현재 게임 상태에 대한 정보를 넘겨준다.
        anim.SetFloat("speed", 0);
    }

    void UpdateDie()
    {

    }

    void Update()
    {
        switch (_state)
        {
            case PlayerState.Idle:
                UpdateIdle();
                break;
            case PlayerState.Moving:
                UpdateMoving();
                break;
            case PlayerState.Die:
                UpdateDie();
                break;
        }
    }

    void OnMouseClicked(Define.MouseEvent evt)
    {
        if (_state == PlayerState.Die)
            return;

        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);

        RaycastHit hit;
        if (Physics.Raycast(ray, out hit, 100.0f, LayerMask.GetMask("Wall")))
        {
            _destPos = hit.point;
            _state = PlayerState.Moving;
        }
    }
}

마우스 클릭을 통해서만 플레이어가 이동을 하도록 변경하였다. 동시에 마우스 버튼을 누르고 있을 때도 플레이어 이동이 가능하도록 if (evt == press) 문을 삭제하였다.

기존 PlayerController의 Update()에서 사용되던 코드를 세부적으로 나눠서 UpdateMoving, UpdateIdle, UpdateDie에서 실행되도록 하였다. (State 패턴)
따라서 _movetoDest라는 bool 값의 변수를 삭제하고, _movetoDest의 값을 변화시키는 코드를 모두 _state를 변화시키는 코드로 변경하였다.

또한 UpdateMoving, UpdateIdle 함수 내에 플레이어의 애니메이션을 설정하는 코드를 추가하여 각 상태마다 알맞은 애니메이션이 나오도록 하였다.

profile
클라이언트 개발자 지망생

0개의 댓글