Home [Unity] 상태 패턴을 이용한 캐릭터 움직임 구현
Post
Cancel

[Unity] 상태 패턴을 이용한 캐릭터 움직임 구현

적용된 FSM(유저 행동)

unity_img_05

1. 구현 방법

Unity_img_06

2. Player(Object)

  • 유저의 Input 값에 따른 상태 변경만 관리
  • 상태 변화 및 상태에 따른 행동은 state Machine에서 관리

Input 값에 따른 상태 변경 예시 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void Update()
{
    HandleInput();
}

/// <summary>
/// 유저의 Input Data를 통해서 어떤 상태로 변화할지 관리해주는 메소드
/// </summary>
void HandleInput()
{
    // 공격일 때
    if (Input.GetButton("Fire1"))
    {
        if(stateMachine.CurrentState == dicStates.GetOrDefault(EState.IDLE) ||
            stateMachine.CurrentState == dicStates.GetOrDefault(EState.RUN))
        {
            stateMachine.SetState(dicStates.GetOrDefault(EState.ATTACK));
        }
    }

    // 움직일 떄 (W, A, S, D)
    if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
    {
        if(stateMachine.CurrentState == dicStates.GetOrDefault(EState.IDLE))
        {
            stateMachine.SetState(dicStates.GetOrDefault(EState.RUN));
        }
    }
}

3. State Machine

  • 상태 변화에 따른 실제 내부 작동을 정의
  • 말 그대로, State를 돌려주는 기계

State Machine 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace StatePattern
{
    /// <summary>
    /// StateMachine 
    /// </summary>
    public class StateMachine
    {
        public IState CurrentState { get; private set; }

        /// <summary>
        /// Default State로 처음 세팅되도록 설정
        /// </summary>
        /// <param name="defaultState"></param>
        public StateMachine(IState defaultState)
        {
            CurrentState = defaultState;
        }

        /// <summary>
        /// State 세팅
        /// </summary>
        /// <param name="state"></param>
        public void SetState(IState state)
        {
            if (state == null)
                return;

            if(CurrentState == state)
            {
                DebugHelper.LogError(state.GetType() + " - 같은 상태 반복");
                return;
            }

            // State 변경 전, OperateExit() 메소드 실행
            CurrentState.OperateExit();

            CurrentState = state;

            // State 변경 후, OperateEnter() 메소드 실행
            CurrentState.OperateEnter();
        }

        /// <summary>
        /// State가 매 프레임마다 실행해야 할 행동 실행
        /// </summary>
        public void DoOperateUpdate() => CurrentState.OperateUpdate();
    }
}

4. State Class

  • 각 상태별로 수행해야 할 내용들을 정의
  • 이렇게 함으로써 특정 상태에 수정이 필요할 때 그 상태를 정의한 Class만 확인하면 된다
This post is licensed under CC BY 4.0 by the author.