Humility

아무리 노력해도 최고가 되지 못할 수 있다⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀그럼에도 노력하는자가 가장 겸손한 것 아닌가

공부하는 블로그

유니티/디자인패턴

[Unity] 유니티 C#) State 패턴

새벽_글쓴이 2024. 12. 2. 13:34
반응형

State 패턴

객체의 내부 상태에 따라 동작을 변경할 수 있게 해주는 디자인 패턴

 

기본 구현 방법

상태 인터페이스 정의

public interface IState
{
    void Enter();  // 상태 진입시 호출
    void Execute(); // 상태 실행중 호출
    void Exit();   // 상태 종료시 호출
}

 

상태를 관리할 매니저 클래스

public class StateManager : MonoBehaviour
{
    private IState currentState;
    
    void Start()
    {
        // 초기 상태 설정
        SetState(new IdleState());
    }

    void Update()
    {
        // 현재 상태 실행
        if (currentState != null)
            currentState.Execute();
    }

    // 상태 변경 메서드
    public void SetState(IState state)
    {
        if (currentState != null)
            currentState.Exit();
            
        currentState = state;
        currentState.Enter();
    }
}

 

구체적인 상태 클래스 구현

public class IdleState : IState
{
    public void Enter()
    {
        Debug.Log("Idle 상태 시작");
        // 초기화 코드
    }

    public void Execute()
    {
        // Idle 상태에서의 동작
        Debug.Log("Idle 상태 실행중");
    }

    public void Exit()
    {
        Debug.Log("Idle 상태 종료");
        // 정리 코드
    }
}

// 다른 상태 예시
public class WalkState : IState
{
    private Transform transform;
    private float speed = 5f;

    public WalkState(Transform transform)
    {
        this.transform = transform;
    }

    public void Enter()
    {
        Debug.Log("Walk 상태 시작");
    }

    public void Execute()
    {
        // 걷기 동작 구현
        float horizontalInput = Input.GetAxis("Horizontal");
        transform.Translate(new Vector3(horizontalInput * speed * Time.deltaTime, 0, 0));
    }

    public void Exit()
    {
        Debug.Log("Walk 상태 종료");
    }
}

 

상태 전환 방법

// StateManager를 참조하여
StateManager stateManager = GetComponent<StateManager>();

// 새로운 상태로 전환
stateManager.SetState(new WalkState(transform));

 

State 패턴의 구조적 특징

  • IState 인터페이스로 모든 상태가 구현해야 할 메서드를 정의한다
  • 각 상태는 독립적인 클래스로 구현되어 있어 관리가 용이하다
  • Player 클래스는 현재 상태만 참조하고, 상태 전환을 관리한다

 

주요 장점

  • 코드의 가독성이 향상된다
  • 새로운 상태 추가가 용이하다
  • 상태별 로직이 분리되어 있어 유지보수가 쉽다
  • if-else 문의 복잡성을 줄일 수 있다

 

활용 사례

  • 캐릭터 동작 관리 (이동, 점프, 공격 등)
  • AI 행동 패턴 구현
  • UI 상태 관리
  • 게임 시스템 상태 관리

 

State패턴과 FSM의 차이

이 둘은 비슷해 보이지만 몇가지 중요한 차이점이 있다

 

1. 추상화 수준 차이

FSM은 더 높은 수준의 개념/아키텍처이다.
상태와 전이를 정의하는 수학적 모델이자 추상적인 개념이다

상태 패턴은 FSM을 구현하는 여러 방법 중 하나이다.
객체 지향 디자인 패턴으로서 FSM을 클래스 구조로 구현하는 구체적인 방법이다

 

2. 구현 방식의 차이

FSM은 여러 가지 방식으로 구현될 수 있다
열거형과 switch문 사용
상태 전이 테이블 사용
상태 패턴 사용
기타 다른 구현 방식들

상태 패턴은 특정한 구현 방식을 제안한다
각 상태를 클래스로 캡슐화
인터페이스를 통한 상태 동작 정의
상태 전환 로직을 각 상태 클래스 내부에 포함

 

3. 유연성과 확장성

FSM은 단순한 구현(예: switch문 사용)의 경우 코드 수정이 어려울 수 있다

상태 패턴은 새로운 상태 추가가 용이하고, 각 상태의 로직을 독립적으로 수정할 수 있어 더 유연하다

 

4.사용 목적

FSM은 주로 시스템의 전반적인 상태 관리와 전이를 모델링하는 데 중점을 둔다

상태 패턴은 객체의 내부 상태에 따른 행동 변화를 캡슐화하는 데 중점을 둔다.

 

사용 예시

FSM

public enum State { Idle, Walk, Jump }

public class CharacterFSM : MonoBehaviour
{
    private State currentState;

    void Update()
    {
        switch (currentState)
        {
            case State.Idle:
                HandleIdleState();
                break;
            case State.Walk:
                HandleWalkState();
                break;
            case State.Jump:
                HandleJumpState();
                break;
        }
    }
}

 

상태 패턴

public interface IState
{
    void Update();
}

public class IdleState : IState
{
    public void Update()
    {
        // Idle 상태 처리
    }
}

public class Character
{
    private IState currentState;
    
    public void SetState(IState state)
    {
        currentState = state;
    }

    public void Update()
    {
        currentState.Update();
    }
}

 

FSM"무엇"을 할것인지 정의하는 개념
상태패턴"어떻게" 구현할 것인지 정의하는 방법이다

결론적으로 상태패턴은 FSM을 객체 지향적으로 구현하는 한 가지 방법인 것이다.

 

반응형