객체의 내부 상태에 따라 스스로 행동을 변경
상태를 클래스로 캡슐화하고, 상태 전환을 클래스 간의 참조 변경으로 처리
게임에서는 캐릭터 애니메이션 상태, 네트워크 연결 상태, 툴 상태 등이 있다.
장점
유연한 상태전환: 상태를 캡슐화하여 상태 전환 로직을 각 상태 클래스에 분리
상태 전환을 더 쉽게 관리하고 확장할 수 있게 함
가독성 향상: 상태 전환 로직이 각 상태 클래스에 분리되어 있어, 코드의 가독성이 향상
유지보수 용이성: 상태를 추가 및 변경 시, 다른 상태 클래스의 영향 없이독립적으로 작업
단점
클래스 증가: 상태별로 별도의 클래스가 필요하기 때문에 클래스의 수가 증가
복잡성 증가: 상태가 많아질수록 관리해야 할 클래스와 코드의 복잡성이 증가
규모에 따라서 적용할지 판단하자. 작은 프로젝트, 적은 상태들인 경우에 적용하면 클래스가 많아지며 코드를 파악하지 어려울 수 있음.
시스템이 가질 수 있는 모든 상태와, 한 상태에서 다른 상태로 전환하는 규칙을 정의하는 모델
상태패턴을 구현하려고 했을 때, 가장 먼저 떠오르는건 Switch - case로 각 상태에 동작을 호출하는 방법이 떠오른다.(저는 그렇습니다.)
FSM에서는 이를 인터페이스로 분리하여 관리해준다.
먼저 IState 인터페이스에 Enter, Update, Exit 메소드를 두어 각 상태에 들어가고 들어갔을 때 처리될, 상태에서 빠져나올 때로 구분한다. 상황에 맞게 커스텀해도 좋을 듯 하다. 이는 기본적인(보통의 경우?)이니 바뀌어도 좋다.
다음으로는 StateMachine클래스를 만들어보자.
public class StateMachine
{
public IState CurrentState { get; private set; }
public WalkState walkState;
public JumpState jumpState;
public IdleState idleState;
public StateMachine(PlayerController player)
{
this.walkState = new WalkState(player);
this.jumpState = new JumpState(player);
this.idleState = new IdleState(player);
}
public void Initialize(IState startState)
{
CurrentState = startState;
startState.Enter();
}
public void TransitionTo(IState nextState)
{
CurrentState.Exit();
CurrentState = nextState;
CurrentState.Enter();
}
public void Update()
{
if(CurrentState != null)
{
CurrentState.Update();
}
}
}
다음과 같이 추가될 상태들을 추가해주고 각 클래스에서 구현해주면 된다.