State Machine (상태 기계) 시스템 설명
1. State Machine이란?
State Machine(상태 기계)은 객체의 상태를 체계적으로 관리하는 디자인 패턴입니다. 객체가 가질 수 있는 여러 상태들을 정의하고, 상태 간의 전환을 관리하는 시스템입니다.
핵심 개념: 상태(State), 전환(Transition), 이벤트(Event)
2. State Machine의 주요 구성 요소
2.1 상태(State)
- 객체가 가질 수 있는 특정 조건이나 모드
- 각 상태는 고유한 동작과 속성을 가짐
- 예: 대기 상태, 이동 상태, 점프 상태 등
2.2 전환(Transition)
- 한 상태에서 다른 상태로 이동하는 조건
- 이벤트나 조건에 의해 발생
- 예: 점프 버튼 입력 → 대기 상태에서 점프 상태로 전환
2.3 이벤트(Event)
- 상태 전환을 유발하는 외부 요인
- 사용자 입력, 시간 경과, 물리적 충돌 등
3. Unity에서의 State Machine 구현
3.1 기본 구조
public abstract class State<T>
{
// 상태 진입 시 호출
public virtual void Enter() { }
// 상태 업데이트 시 호출
public virtual void Update() { }
// 상태 종료 시 호출
public virtual void Exit() { }
// 상태 전환 조건 검사
public virtual bool CanTransitionTo(State<T> nextState)
{
return true;
}
}
public class StateMachine<T>
{
private State<T> currentState;
private T owner;
public StateMachine(T owner)
{
this.owner = owner;
}
public void ChangeState(State<T> newState)
{
if (currentState != null && !currentState.CanTransitionTo(newState))
return;
currentState?.Exit();
currentState = newState;
currentState?.Enter();
}
public void Update()
{
currentState?.Update();
}
}
3.2 플레이어 상태 구현 예시
public class Player : MonoBehaviour
{
private StateMachine<Player> stateMachine;
private CharacterController controller;
private Vector3 velocity;
private Animator animator;
private void Start()
{
controller = GetComponent<CharacterController>();
animator = GetComponent<Animator>();
stateMachine = new StateMachine<Player>(this);
stateMachine.ChangeState(new IdleState());
}
private void Update()
{
stateMachine.Update();
}
}
public class IdleState : State<Player>
{
public override void Enter()
{
Debug.Log("Idle 상태 진입");
Owner.animator.SetBool("IsMoving", false);
}
public override void Update()
{
// 이동 입력이 있으면 Walk 상태로 전환
if (Input.GetAxis("Horizontal") != 0 ||
Input.GetAxis("Vertical") != 0)
{
Owner.ChangeState(new WalkState());
}
}
public override void Exit()
{
Debug.Log("Idle 상태 종료");
}
}
public class WalkState : State<Player>
{
private float moveSpeed = 5f;
public override void Enter()
{
Debug.Log("Walk 상태 진입");
Owner.animator.SetBool("IsMoving", true);
}
public override void Update()
{
Vector3 moveInput = new Vector3(
Input.GetAxis("Horizontal"),
0,
Input.GetAxis("Vertical")
);
if (moveInput.magnitude == 0)
{
Owner.ChangeState(new IdleState());
return;
}
// 이동 처리
Owner.controller.Move(moveInput * moveSpeed * Time.deltaTime);
// 애니메이션 파라미터 업데이트
Owner.animator.SetFloat("MoveSpeed", moveInput.magnitude);
}
public override void Exit()
{
Debug.Log("Walk 상태 종료");
}
}
4. 애니메이션 상태 관리
4.1 애니메이션 파라미터
- Bool 파라미터: 상태 전환을 위한 플래그 (예: IsMoving, IsJumping)
- Float 파라미터: 연속적인 값 표현 (예: MoveSpeed, BlendTree)
- Trigger 파라미터: 일회성 이벤트 (예: Attack, Hit)
4.2 애니메이션 블렌딩
public class AnimationBlendState : State<Player>
{
private float blendTime = 0.3f;
private float currentBlend = 0f;
public override void Enter()
{
currentBlend = 0f;
Owner.animator.SetFloat("BlendValue", 0f);
}
public override void Update()
{
currentBlend = Mathf.MoveTowards(currentBlend, 1f, Time.deltaTime / blendTime);
Owner.animator.SetFloat("BlendValue", currentBlend);
if (currentBlend >= 1f)
{
Owner.ChangeState(new NextState());
}
}
}
애니메이션 상태 전환 예시:
Idle → Walk → Run → Jump → Fall
5. State Machine의 장점
- 코드 구조화: 복잡한 로직을 상태별로 분리하여 관리
- 유지보수성: 상태별 독립적인 수정 가능
- 확장성: 새로운 상태 추가가 용이
- 디버깅 용이: 상태 전환 추적이 쉬움
6. 게임 개발에서의 활용
6.1 캐릭터 AI
- 적 캐릭터의 행동 패턴 관리
- 전투 상태 관리 (공격, 방어, 회피 등)
6.2 플레이어 컨트롤
- 이동, 점프, 공격 등의 상태 관리
- 애니메이션 상태 관리
6.3 UI 시스템
- 메뉴 상태 관리
- 팝업 시스템
7. 주의사항
- 상태 전환 조건을 명확히 정의
- 상태 간의 의존성을 최소화
- 상태 스택 관리에 주의 (중첩된 상태)
- 메모리 관리 (상태 객체 생성/소멸)
8. 결론
State Machine은 게임 개발에서 매우 유용한 디자인 패턴입니다. 복잡한 객체의 상태를 체계적으로 관리하고, 코드의 가독성과 유지보수성을 높여줍니다. 특히 Unity와 같은 게임 엔진에서는 캐릭터 AI, 플레이어 컨트롤, UI 시스템 등 다양한 분야에서 효과적으로 활용될 수 있습니다.
LIST
'Unity' 카테고리의 다른 글
TIL - Addressable 설계 (2) | 2025.04.23 |
---|---|
계층형 유한 상태 머신 (0) | 2025.04.09 |
Unity Custom Editor - 윈도우 만들기 (0) | 2025.04.06 |
프로토타입 패턴 (0) | 2025.04.06 |
Unity UI 최적화 (1) | 2025.03.30 |