[Unity] State 패턴

Yerin·2023년 7월 18일
0

상태가 여러가지일 경우 Update 함수에서 모두 처리한다면
매우 복잡한 상황이 발생한다.

PlayerState를 변수화하여 처리하자!

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

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

    Vector3 _destPos;

    void Start()
    {
        //Managers.Input.KeyAction -= OnKeyboard;
       // Managers.Input.KeyAction += OnKeyboard;
        Managers.Input.MouseAction -= OnMouseClicked;
        Managers.Input.MouseAction += OnMouseClicked;
    }

    float wait_run_ratio = 0;

    public enum PlayerState
    { 
        Die,
        Moving,
        Idle,
    }
    PlayerState _state = PlayerState.Idle;


    void UpdateDie()
    { 
        // 아무것도 못함
    }

    void UpdateMoving()
    {

        Vector3 dir = _destPos - transform.position;
        if (dir.magnitude < 0.0001f)
        {
            _state = PlayerState.Idle;
        }
        else
        {
            float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, dir.magnitude);
            transform.position += dir.normalized * moveDist;
            transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 20 * Time.deltaTime);
        }

        //애니메이션 
        wait_run_ratio = Mathf.Lerp(wait_run_ratio, 1, 10.0f * Time.deltaTime);
        Animator anim = GetComponent<Animator>();
        anim.SetFloat("wait_run_ratio", wait_run_ratio);
        anim.Play("WAIT_RUN");


    }

    void UpdateIdle()
    {
        //애니메이션
        wait_run_ratio = Mathf.Lerp(wait_run_ratio, 0, 10.0f * Time.deltaTime);
        Animator anim = GetComponent<Animator>();
        anim.SetFloat("wait_run_ratio", wait_run_ratio);
        anim.Play("WAIT_RUN");
    }

    void Update()
    {

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

💡 State 형식으로 관리할 경우, 예를 들어 Player가 Die 상태였을 때 다른 Player가 부활을 시킨 경우 Idle로 변경만 해주면 된다는 것이 쉽게 된다. 💡
❗ 단, 위의 단점은 동시에 두개의 상태를 가지는 경우는 처리가 힘들게 된다. ❗

profile
재밌는 코딩 공부

0개의 댓글