
Unity 유한상태머신 (FSM)에 대하여
게임 개발을 하다 보면, 특히 AI나 캐릭터의 행동 패턴을 구현할 때 "상태"를 기반으로 한 시스템이 필요해지는 경우가 많습니다. 이럴 때 자주 활용되는 개념이 바로 유한상태머신(Finite State Machine, FSM) 입니다. 이번 글에서는 Unity에서 FSM을 어떻게 구현하고 활용할 수 있는지에 대해 정리해보겠습니다.
FSM(Finite State Machine)이란?
FSM은 하나의 객체가 여러 상태 중 하나의 상태에만 속하고, 조건에 따라 다른 상태로 전이(transition)되는 구조를 가진 논리 모델입니다. 상태마다 서로 다른 동작을 정의할 수 있으며, 이를 통해 복잡한 행동 로직을 깔끔하게 구성할 수 있습니다.
예를 들어, 적 캐릭터 AI의 FSM은 다음과 같이 구성될 수 있습니다:
- Idle: 대기 상태
- Patrol: 경로를 따라 이동
- Chase: 플레이어를 발견하고 추격
- Attack: 사정거리 내에 들어온 플레이어를 공격
- Dead: 체력이 0이 되어 사망
각 상태는 전이 조건에 따라 서로 전환될 수 있습니다.
상태 다이어그램 예시
아래는 간단한 FSM 상태 다이어그램 예시입니다:
[Idle] ---> (플레이어 감지) ---> [Chase] ---> (사거리 안) ---> [Attack]
^ | |
| |(플레이어 사라짐) |(플레이어 죽음)
| v v
[Patrol] <--- (시간 경과) <--- [Return] <--- [Dead]
이러한 다이어그램은 상태 간 흐름을 직관적으로 파악하는 데 큰 도움이 됩니다.
Unity에서 FSM을 구현하는 방법
Unity에서는 FSM을 구현하는 방법이 다양합니다. 대표적으로는 다음과 같은 방식이 있습니다.
1. Enum + Switch문 기반 FSM
가장 간단한 방식으로, 현재 상태를 enum으로 관리하고 Update()에서 switch문을 활용해 상태별 로직을 처리합니다.
public enum EnemyState { Idle, Patrol, Chase, Attack, Dead }
public class EnemyFSM : MonoBehaviour
{
public EnemyState currentState;
void Update()
{
switch (currentState)
{
case EnemyState.Idle:
HandleIdle();
break;
case EnemyState.Patrol:
HandlePatrol();
break;
// 기타 상태들...
}
}
}
2. 상태를 클래스화한 방식 (OOP FSM)
상태를 각각 클래스(또는 ScriptableObject)로 분리해 SOLID 원칙에 가깝게 구현하는 방식입니다. 확장성과 유지보수에 매우 유리합니다.
public abstract class State
{
protected EnemyFSM fsm;
public State(EnemyFSM fsm) => this.fsm = fsm;
public abstract void Enter();
public abstract void Execute();
public abstract void Exit();
}
public class PatrolState : State
{
public PatrolState(EnemyFSM fsm) : base(fsm) {}
public override void Enter() { Debug.Log("Patrol 시작"); }
public override void Execute() { /* 경로 이동 로직 */ }
public override void Exit() { Debug.Log("Patrol 종료"); }
}
public class EnemyFSM : MonoBehaviour
{
State currentState;
void Update()
{
currentState?.Execute();
}
public void ChangeState(State newState)
{
currentState?.Exit();
currentState = newState;
currentState.Enter();
}
}
이 방식은 상태 전환을 유연하게 처리할 수 있어 복잡한 AI 로직이나 보스 몬스터의 동작 구현에 적합합니다.
FSM을 사용할 때의 장점
- 코드가 깔끔해짐: 상태별로 기능이 나눠져 가독성과 유지보수가 쉬움
- 확장성 좋음: 새로운 상태를 추가해도 기존 로직과 충돌이 없음
- 디버깅 용이: 현재 상태만 확인하면 문제를 빠르게 파악 가능
Unity Animator와의 차이점
Unity의 Animator도 일종의 FSM 구조를 사용합니다. 애니메이션의 상태 전이 및 조건 설정을 시각적으로 설정할 수 있지만, 논리적인 FSM은 직접 구현해야 더욱 복잡한 게임 로직을 처리할 수 있습니다.
- Animator FSM: 애니메이션 전이용 시각화 도구
- 코드 FSM: 캐릭터의 행동 전반을 제어하는 논리 시스템
마무리: 언제 FSM을 쓰면 좋을까?
FSM은 특히 적 AI, NPC 행동, 보스 패턴, UI 상태 제어 등에 매우 유용합니다. 단순한 로직이라면 enum + switch로도 충분하고, 복잡한 경우에는 클래스 기반 FSM으로 구조화하는 것을 추천합니다.
FSM 구조를 잘 잡아두면 향후 확장할 때 큰 도움이 되니, 처음부터 설계를 신중히 하면 좋습니다.
필요하다면 FSM 구조 템플릿이나 실제 게임 예시 코드도 다음 글에서 다뤄볼 예정입니다!
'Unity' 카테고리의 다른 글
| Unity에서 CompareTag를 사용하는 이유와 주의사항 (0) | 2025.04.15 |
|---|---|
| Unity 애니메이션에 대하여 (0) | 2025.04.14 |
| Unity에서 방향 벡터 계산 시 실수하기 쉬운 예시 (0) | 2025.04.11 |
| Unity에서 특별한 폴더들과 폴더들의 역할 (0) | 2025.04.10 |
| Unity 전처리 지시문(Preprocessor Directive)과 XML 주석 (0) | 2025.04.08 |