2024. 6. 17. 21:19ㆍUnity/Unity 학습정리
FSM 유한상태머신이다. 유한한 여러 상태가 존재하는데 여러 상태중 한 개의 상태만 가질 수 있고 상황 혹은 유저의 인풋 여러 요인으로 상태가 변화하는 것을 관리해주는 디자인 패턴이다. 구조적으로 잘 구성되어있고 애니메이션도 상태에 따라서 넣어 줄 수 있으며, 상당히 복잡한 행동을 하는 객체가 아니면 매우 유용하다.
FSM 구조
FSM은 디자인 패턴이기 때문에 구조 자체는 여러 구조로 나타낼 수 있다. 가장 간단한 구조가 Switch문을 이용해 구현하는 것이다.
public enum State
{
Idle,
Run,
Walk
}
switch(State)
{
case(Idle): Debug.Log("가만히 있다");
case(Run): Debug.Log("달린다");
case(Walk): Debug.Log("걷다");
}
구조가 간단한 만큼 확장성에서 떨어진다. 매번 Switch문을 참조해야하고 Idle에서 하던 행위를 취소하고 다른 행위로 넘어가야 할 때도 써야하는 코드가 길어지고 가독성에서도 불편할 것이다.
다음은 StateMachine을 이용해서 구현하는 방식이다.
public interface IState
{
public void Enter();
public void Exit();
public void Update();
public void PhysicsUpdate();
}
public abstract class StateMachine
{
protected IState currentState;
public void ChangeState(IState state)
{
currentState?.Exit();
currentState = state;
currentState?.Enter();
}
public void Update()
{
currentState?.Update();
}
public void PhysicsUpdate()
{
currentState?.PhysicsUpdate();
}
}
위 StateMachine은 세 가지의 일을 한다.
- State가 바뀔때마다 기존 상태에서 Exit() 새로운 상태를 Enter()하면서 이전 상태를 완전히 초기화하고 새로운 상태를 넣는다.
- Update를 통해 현재 상태에서 해야하는 Update만 Update를 해준다.
- PhysicsUpdate도 마찬가지이다.
public class PlayerBaseState : IState
{
protected PlayerStateMachine stateMachine;
protected PlayerData playerData;
public PlayerBaseState(PlayerStateMachine stateMachine)
{
this.stateMachine = stateMachine;
playerData = stateMachine.player.data.PlayerData;
}
public virtual void Enter()
{
}
public virtual void Exit()
{
}
public virtual void Update()
{
}
public virtual void PhysicsUpdate()
{
}
}
IState를 상속받는 PlayerBaseState는 뼈대를 만들수 있다.
Enter(),Exit(),Update(),PhysicsUpdate(), 여기서 물론 업데이트 문은 Monobehaviour에서 가져온 속성이 아니기 때문에 인 게임에서 프레임당 수행하는 함수들은 아니다. 대신 해당 업데이트 구문들은 모두 StateMachine에서 부르고 해당 StateMachin을 사용하는 MonoBehaviour를 상속받는 객채에서 불러서 사용한다.
public class PlayerIdleState : PlayerBaseState
{
public PlayerIdleState(PlayerStateMachine stateMachine) : base(stateMachine)
{
}
public override void Enter()
{
stateMachine.movementSpeedModifier = 0f;
base.Enter();
Debug.Log("IdleMode");
StartAnimation(stateMachine.player.AnimationData.idleParameterHash);
}
public override void Exit()
{
base.Exit();
Debug.Log("idleOut");
StopAnimation(stateMachine.player.AnimationData.idleParameterHash);
}
public override void Update()
{
base.Update();
if(IsInChasinginRange())
{
stateMachine.ChangeState(stateMachine.chasingState);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
}
}
그리고 PlayerBaseState를 상속받은 여러 State중 하나인 IdleState이다. 해당 State에서 상속받은 함수들을 모두 해당 State에서 원하는 동작을하게 수정을 해준다.
다음 포스팅에서는 Animation과의 연계에 대해서 포스팅할 예정이다.
'Unity > Unity 학습정리' 카테고리의 다른 글
Unity - FSM(Finite State Machine)(3) (0) | 2024.06.20 |
---|---|
Unity - FSM(Finite State Machine)(2) (0) | 2024.06.18 |
Unity - 슬라이더바로 사운드 조절하기 (1) | 2024.06.05 |
Unity - Scriptable Object (0) | 2024.05.27 |
Unity - Object Pool (0) | 2024.05.23 |