반응형
FSM이란?
FSM은 프로그램에서 객체의 행동을 여러 상태(State)로 나누고 현재 상태에 따라 객체의 행동을 다르게 설정하는 설계 패턴이다.
예시 : Idle → 플레이어 발견 → Chase → 공격 범위 안 → Attack
FSM 핵심 구성 요소
1. 상태(State) - 객체의 행동 단위, 각 상태는 독립적인 로직을 가짐
2. 전이(Transition) - 특정 조건이 만족되면 상태 변경 발생
3. 상태 머신(StateMachine) - 현재 상태 추적 및 전이 관리
4. State Owner(상태 주체) - FSM을 실행하는 객체
사장(State Owner) vs 직원(State) vs 회사(StateMachine)
01 사장(State Owner)
FSM을 사용하는 주체 ex) 적 AI
상태를 바꾸고 싶으면 자신의 FSM인스턴스에 요청
public class EnemyController<T> : MonoBehaviour, IStateMachineOwner<T>
{
protected StateMachine<T> _fsm = new StateMachine<T>();
void Start()
{
ChangeState(new IdleState());
}
void Update()
{
_fsm.Update(this as T);
}
public void ChangeState(IState<T> _currentState)
{
_fsm.ChangeState(_currentState, this as T);
}
}
IStateMachineOwner<T>이 왜 필요할까?
상태 내부에서 아래처럼 상태 전이를 하고 싶을 때 문제가 발생한다.
public class ChaseState : IState<T> // T = EnemyController
{
public void Update(T owner)
{
owner.ChangeState(new AttackState()); // 오류 발생 가능
}
}
여기서 T는 제네릭이기 때문에 ChangeState가 존재한다는 걸 보장할 수 없다. 그래서 컴파일 에러가 발생할 수 있다.
그래서 IStateMachineOwner가 필요하다. 이렇게 하면 타입안전성이 보장된다.
02 직원(State)
실제 업무를 수행하는 객체이다. 보통 Enter, Update, Exit 메서드를 가진다.
public interface IState<T>
{
void Enter(T obj);
void Update(T obj);
void Exit(T obj);
}
03 회사(StateMachine)
현재 어떤 직원(State)이 일하고 있는지 관리한다. Update가 매 프레임 호출되며 현재 상태의 Update를 대신 호출한다. 상태가 바뀌면 Exit() → Enter순서대로 호출된다.
public class StateMachine<T>
{
private IState<T> _cuurentState;
// state바뀔때 기존꺼 나가고 새로운거 enter
public void ChangeState(IState<T> newState, T obj)
{
_cuurentState?.Exit(obj);
_cuurentState = newState;
_cuurentState?.Enter(obj);
}
public void Update(T obj)
{
_cuurentState?.Update(obj);
}
}
구조 시각화
EnemyController (사장)
└── StateMachine<EnemyController> (회사)
├── IdleState : IState<EnemyController> (직원)
├── ChaseState : IState<EnemyController>
└── AttackState : IState<EnemyController>
반응형
'유니티 공부 > Unity' 카테고리의 다른 글
Unity - InputAction을 사용해서 플레이어 동작 기능 구현하기 (0) | 2025.05.16 |
---|---|
Unity - 제네릭이 꼭 좋은 건 아니였다. (0) | 2025.05.12 |
Unity - Strategy Pattern(전략 패턴)을 사용해 씬에 따라 플레이어의 조작 방식을 달라지게 만들어보자 (0) | 2025.05.07 |
Unity - MissingReferenceException 에러 해결 방법(+) Dontdestroyonload) (0) | 2025.05.02 |
Unity - 상속 구조에서 호출 누락 조심! (0) | 2025.05.01 |
댓글