ABOUT ME

Today
Yesterday
Total
  • 상태(State) 패턴 with Unity
    유니티 2022. 2. 4. 22:03

    1. 상태 패턴

    상태 패턴은 객체에 상태를 정해서 상태에 맞는 로직을 수행하는 디자인 패턴이다.

     

    사용하는 이유

    if와 else로만 구현을 하게되면 스파게티 코드가 될 수 있기 때문에 객체의 상태로 분리시켜서 로직을 수행하면 이러한 문제를 해결할 수 있다.

     

    enum과 swtich를 활용한 상태 패턴

    우선 enum을 통해서 상태를 열거한다.

        public enum PlayerState
        {
            Die,
            Moving,
            Idle,
        }

     

    업데이트문에서 switch문을 통해서 상태에따라 실행될 함수들을 집어넣는다.

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

     

    이런식으로 함수들을 정의하여 이제 상태가 변화하면 그에 맞는 로직을 처리하게끔 구현이 된다.

        void UpdateMoving()
        {
            Vector3 dir = _destPos - transform.position; // 방향값 가져오기
            if (dir.magnitude < 0.001f) // 도착완료하면 false로 설정
            {
                //_moveToDest = false;
                _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), 10 * 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");
        }

    위의 코드는 Idle상태가 기본이었다가 이동명령이 발생하면 Moving상태로 변화하고 이동이 끝나면 다시 Idle상태로 되돌아가는 로직이다.

     

    만약 새로운 기능을 추가하고 싶으면 enum과 switch문에만 상태를 추가하고 로직은 따로 구현만 하면 된다.

    '유니티' 카테고리의 다른 글

    KeyFrame Animation  (0) 2022.02.05
    State Machine  (0) 2022.02.05
    애니메이션(Animation)  (0) 2022.02.04
    마우스 클릭을 통한 플레이어 이동  (0) 2022.02.04
    카메라(Camera)  (0) 2022.02.04
Designed by Tistory.