FSM(Finite State Machine, 유한 상태 기계)

게임 오브젝트의 상태를 체계적으로 관리하고 전환하기 위한 설계 패턴

플레이어나 적 AI처럼 상태에 따라 행동이 달라지는 시스템에 자주 사용

 

사용하는 이유

코드의 가독성과 유지보수성 향상
→ 상태별 로직을 분리해서 각 클래스나 메서드에 구현 가능.

 

복잡한 조건 분기를 명확하게 구조화
→ if-else나 switch 남발 대신 상태 전이 중심 설계.

 

확장성과 재사용성 좋음
→ 새로운 상태 추가 및 전이 조건 설정이 쉬움.

 

IState (상태 인터페이스)

// 상태 인터페이스
public interface IState
{
    void Enter();
    void Execute();
    void Exit();
}

 

역할

모든 상태들이 따라야 할 공통 규칙을 정의

각 상태는 이 인터페이스를 구현(implements)하여, 상태 진입, 유지, 종료 시의 동작을 정의함

 

IdleState, WalkState 등 (상태 클래스들)

 

// Idle 상태
public class IdleState : IState
{
    public void Enter()
    {
        Debug.Log("Idle: Enter");
    }

    public void Execute()
    {
        Debug.Log("Idle: Execute");
    }

    public void Exit()
    {
        Debug.Log("Idle: Exit");
    }
}

// Walk 상태
public class WalkState : IState
{
    public void Enter()
    {
        Debug.Log("Walk: Enter");
    }

    public void Execute()
    {
        Debug.Log("Walk: Execute");
    }

    public void Exit()
    {
        Debug.Log("Walk: Exit");
    }
}

 

역할

실제 상태별 동작을 정의하는 클래스

Enter()에선 애니메이션 시작이나 초기화,
Execute()에선 반복 동작(예: 걷기),
Exit()에선 상태 전환 전 정리 작업 등을 수행

 

StateMachine

public class StateMachine
{
    private IState currentState;

    public void ChangeState(IState newState)
    {
        currentState?.Exit();
        currentState = newState;
        currentState.Enter();
    }

    public void Update() // 생명주기 함수 Update 아님 주의(Execute로 이름 대체 가능)
    {
        currentState.Execute();
    }
}

역할

현재 상태를 기억하고,

새로운 상태로 전이(change)하며,

현재 상태의 로직을 실행(update)하는 중앙 관리자입니다.

즉, 상태 전환과 실행을 통제하는 컨트롤 타워 역할

 

왜 필요할까?

상태 객체만으로는 전환(변경)을 스스로 못함 → 누군가가 상태를 [관리]해줘야 함

StateMachine이 없으면, 상태끼리 서로 직접 호출해야 해서 코드가 복잡하고 꼬이게 됨

상태 전환을 일관되고 안전하게 처리할 수 있음

 

Player (FSM을 사용하는 MonoBehaviour)

public class Character : MonoBehaviour
{
    private StateMachine stateMachine;

    private void Start()
    {
        stateMachine = new StateMachine();
        stateMachine.ChangeState(new IdleState());
    }

    private void Update()
    {
        stateMachine.Update();
        if (Input.GetKeyDown(KeyCode.W))
        {
            stateMachine.ChangeState(new WalkState());
        }
        else if (Input.GetKeyDown(KeyCode.I))
        {
            stateMachine.ChangeState(new IdleState());
        }
    }
}

 

'Unity > 디자인 패턴' 카테고리의 다른 글

전략 패턴  (0) 2025.05.04
싱글톤 패턴  (0) 2025.05.02
오브젝트 풀링 패턴  (0) 2025.03.08

+ Recent posts