호빵의 IT 개발소

[MMO RPG] Animator 본문

C#, 유니티/MMO RPG 만들기 기초(클라이언트)

[MMO RPG] Animator

호빵Stack 2022. 1. 27. 01:25

현재 player를 이동하게 되면 고정된 모션으로 이동하게 됩니다. 실제 게임에서는 이동시 달리는 모션 가만히 있을때는 제자리에서 살짝살짝 움직이는 모습을 보실수 있습니다. Animator를 추가하는 방법을 알아보겠습니다.

 

1. Project 부분에서 우클릭하여 Create -> Animator Controller를 생성합니다.

 

2. 생성된 Animator Controller를 더블클릭하면 Animator를 만들 수 있는 화면이 뜹니다.

 

3. 다운로드 하였던 Idle모션과 RUN 모션을 드래그 드롭하여 넣어줍니다. (Asset Store에 무료로 많은 Animation이 있습니다.)

 

4. Entry를 우클릭하여 Set StateMachine Default State를 클릭하여 WAIT를 클릭합니다.

 

5. WAIT를 우클릭하여 Make Transition을 클릭 후 RUN을 클릭합니다. 반대로 RUN도 똑같이 Make Transition을 클릭 후 WAIT를 클릭하여 줍니다.

 

6. 우측에 Prameters를 클릭하여 float speed를 생성하여 줍니다.

 

7. 이제 WAIT에서 RUN으로 가는 화살표를 클릭하여 float speed를 만든 부분을 적용시켜 줍니다.

-Has Exit Time 해제

-speed / Greater / 0  : 스피드가 0보다 크면!

 

8. 똑같이 RUN에서 WAIT으로 가는 화살표도 설정하여 줍니다.

-Has Exit Time 해제

-speed / ㅣess / 0  : 스피드가 0보다 작으면

 

9. Player를 클릭하여 Add Component를 통해 animator를 추가 한 뒤 드랙그드롭으로 적용하여 줍니다.

 

10. 코드 작성

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

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

    Vector3 _destPos;

    PlayerState _state = PlayerState.Idle; //처음 _state 상태는 Idle이다.

    public enum PlayerState //플레이어 상태 관리
    {
        Die,
        Moving,
        Idle,
    }

    void UpdateDie()
    {

    }

    void UpdateMoving()
    {
        Vector3 dir = _destPos - transform.position; //destPos에서 Player위치를 빼주면 방향벡터가 나온다.
        if (dir.magnitude < 0.0001f) //목적지에 도착했다면 (방향벡터에 오차범위 때문에 아주 작은 값을 적어줍니다.)
        {
            _state = PlayerState.Idle; //움직임 멈춤
        }
        else //도착하지 않았으니 조금 더 움직여야 한다.
        {
            float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, dir.magnitude); //_speed * Time.deltaTime는 min(0)과 max(dir.magnitude) 사이의 값을 보장해야 한다.(캐릭터 떨림 현상)

            transform.position = transform.position + dir.normalized * moveDist; //dir이 지금 방향벡터이지만 크기가 1로 바꾼 상태가 아니므로 normalized를 통해 크기가 1짜리인 하지만 방향은 똑같은 방향벡터가 나옴 그래서 moveDist 만큼을 방향벡터로 이동

            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime); //slerp를 통해 플레이어 좌표, 내가 바라보는 방향, 적당한 회전 수치 순서로 부드럽게 회전 구현
            transform.LookAt(_destPos); //플레이어가 _destPos 방향을 보면서 이동
        }

        //애니메이션
        Animator anim = GetComponent<Animator>(); //애니메이터를 불러온다.
        anim.SetFloat("speed", _speed); //움직일 때는 캐릭터에 _speed를 Animator에 있는 speed 값에 적용시켜준다.
    }

    void UpdateIdle()
    {
        Animator anim = GetComponent<Animator>();
        anim.SetFloat("speed", 0); //움직이지 않을때는 Animator에 있는 speed 값은 0이 된다.
    }

    void Start()
    {
        Managers.Input.MouseAction -= OnMouseClicked; //다른 곳에서 구독신청 되어있으면 끊어주고
        Managers.Input.MouseAction += OnMouseClicked; //InputManager에게 마우스가 클릭되면 이 함수를 실행해주세요
    }

    void Update()
    {
        switch (_state) //플레이어 상태에 대한 switch문
        {
            case PlayerState.Die:
                UpdateDie();
                break;
            case PlayerState.Moving:
                UpdateMoving();
                break;
            case PlayerState.Idle:
                UpdateIdle();
                break;
        }
    }

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

        //RayCasting
        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;
        }
    }
}

 

 

---------------------------------------------------------------------------------------------------------------------------

참고 : [인프런] Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티  엔진

Comments