State Pattern
public enum StateList
{
Idle, Move, Jump, Attack
}
public class PlayerState : MonoBehaviour
{
private int _direction;
[SerializeField] private StateList CurrentState;
private void Update()
{
// 키 입력 에 따른 각 상태 변화
}
private void Idle()
{
// 기능 로직
// 애니메이션 변화 로직
// 예외처리 등
}
private void Move()
{
// 기능 로직
// 애니메이션 변화 로직
// 예외처리 등
}
private void Jump()
{
// 기능 로직
// 애니메이션 변화 로직
// 예외처리 등
}
private void Attack()
{
// 기능 로직
// 애니메이션 변화 로직
// 예외처리 등
}
}
상태(State)가 늘어나면, 조건 분기수(if) 기하급수적으로 늘어남.-> 게임 기능이 늘어나면 조건문을 늘리는 게 아니라 상태(State)를 늘린다
-> 어떤 객체가 특정 상황에서 어떻게 행동해야 하는지를 결정하는 행동 규칙
void Update()
{
HandleInput();
ApplyGravity();
CheckGround();
if (_state == PlayerState.Idle)
{
...
}
else if (_state == PlayerState.Move)
{
...
}
else if (_state == PlayerState.Jump)
{
...
if (CanDoubleJump()) ...
if (InputDash()) ...
if (InputAttack()) ...
if (IsHit()) ...
}
else if (_state == PlayerState.AirAttack)
{
...
if (ComboWindowOpen()) ...
if (IsHit()) ...
if (IsGrounded()) ...
}
else if (_state == PlayerState.Hit)
{
...
if (RecoverTimeOver()) ...
}
else if (_state == PlayerState.Die)
{
...
}
// 계속 증가
}
상태(State)가 서로를 안다. (엮여있다)Player한테 몰리는 현상이 일어난다.State Pattern 구조
| 요소 | 책임 | 하면 안되는 것 |
|---|---|---|
| Player | 상태 실행 | 상태 로직 직접 구현 |
| StateMachine | 상태 교체 | 입력처리 |
| ConcreteState | 자기 상태 행동 전달 | 다른 상태 내부 접근 |

[동작 흐름]
User Input -> Player -> StateMachine -> State.Update()
입력 -> 코드 FSM -> 물리 -> Animator
코드 FSM 위에서 동작 Animator는 그 위에 얹힌 표현 계층[전환 흐름]
CurrentState?.Exit()
↓
NewState.Enter()
using UnityEngine;
// 입력 처리 / 물리 판정 / 애니메이션 결정
public class PlayerController : MonoBehaviour
{
Rigidbody2D _rb;
Animator _animator;
StateMachine _stateMachine;
// Player가 사용할 State들
IdleState Idle;
MoveState Move;
JumpState Jump;
void Start()
{
_stateMachine = new StateMachine();
Idle = new IdleState(this);
Move = new MoveState(this);
Jump = new JumpState(this);
_stateMachine.ChangeState(Idle);
}
void Update()
{
_stateMachine.Update();
}
public void ChangeState(IState state)
{
_stateMachine.ChangeState(state);
}
}
정리
[Player가 모든 상태를 관리하는 코드 문제점]
상태(State)가 늘어날수록 Player가 모든 상태 관련 것들을 알아야함[상태(State) 역할]
상태(게임 로직 + 애니메이션) 모두 Player 안에서 처리[상태(State) 분리로 일어난 이점]