Finite State Machine 유한상태머신
상태를 기반으로 동작을 제어하는 방식을 구현하는 디자인 패턴
여러가지 상태들을 클래스나 함수로 나눠서 그 상태마다 알맞은 동작을 수행하도록 해준다.
enum State
{
Idle, Move, Trace, Attack, Die
}
이런 상태들이 존재할 때
void Update()
{
switch (state)
{
case State.Idle:
Idle();
break;
case State.Move:
Move();
break;
case State.Trace:
Trace();
break;
case State.Attack:
Attack();
break;
case State.Die:
Die();
break;
}
}
업데이트에서 상태가 어떤지에 따라 함수를 실행할 수 있다.
특정 조건이 만족 되었을 때 상태 변경이 발생하는 것을 말한다.
using UnityEngine;
public interface IState
{
public void Enter();
public void Exit();
public void Update();
public void FixedUpdate();
}
public abstract class StateMachine
{
protected IState currentState;
public void ChangeState(IState state)
{
currentState.Exit();
currentState = state;
currentState.Enter();
}
public void Update()=>currentState?.Update();
}
state머신에서 interface로 각 상태에 들어갈 함수를 선언.
using UnityEngine;
public class MonsterBaseState : IState
{
public virtual void Enter()
{
}
public virtual void Exit()
{
}
public virtual void FixedUpdate()
{
}
public virtual void Update()
{
}
}
베이스를 기반으로
using UnityEngine;
public class MonsterIdleState : MonsterBaseState
{
public override void Enter()
{
}
public override void Exit()
{
}
public override void FixedUpdate()
{
}
public override void Update()
{
// StateMachine의 Update에서 이걸 호출한다.
}
}
using UnityEngine;
public class MonsterTraceState : MonsterBaseState
{
public override void Enter()
{
//추적 상태 시작할 때 행동
}
public override void Exit()
{
//추적 상태 끝날 때 행동
}
public override void FixedUpdate()
{
}
public override void Update()
{
// StateMachine의 Update에서 이걸 호출한다.
}
}
각 상태들의 enter, exit, update등을 생성.
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.PlayerLoop;
public class MonsterStateMachine : StateMachine
{
MonsterIdleState idleState;
MonsterTraceState traceState;
private void Start()
{
currentState = idleState;
ChangeState(traceState);
}
}
MonsterStateMachine에서 StateMachine을 상속받음.
currentState를 사용하여 ChangeState 또는 Update를 사용할 수 있다.
using UnityEngine;
public class MonsterController : MonoBehaviour
{
MonsterStateMachine stateMachine;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
stateMachine.Update();
}
}
최종적으로 MonsterController에서 각 상태의 update를 Update를 불러줌으로써 매 프레임 update를 실행 할 수 있도록 하였음.