Unity 상태 패턴을 활용한 간단한 FSM[TIL 38일차]

장민제·2025년 6월 9일

내일배움캠프

목록 보기
40/41
post-thumbnail

이번 3D 방치형 프로젝트에 몬스터와 플레이어 AI에 상태 패턴을 적용하여 FSM(Finite State Machine)을 간단하게 구현해보았다.

✅ 상태 패턴(State Pattern)이란?

  • 객체의 상태에 따라 행위가 달라지는 상황에서, 각 상태를 클래스로 분리하고 상태 전이를 명확하게 만드는 패턴
  • FSM은 게임 AIUI 상태 전이 등에 자주 사용되며, 상태 간의 전이를 명확하게 정의하고 관리하기 쉬워짐.

📝 구조 요약

1. 기반 클래스: UnitBase

  • 모든 유닛(플레이어, 몬스터)의 공통 기능을 담당합니다. 주요 역할:
  • NavMeshAgent, Animator 등 컴포넌트 관리
  • 현재 유닛의 상태 전이 관리 stateMachine
  • 공통 스탯 (UnitStatSO, unitStat) 및 체력 관리
  • 상태 클래스들을 초기화 및 보유
public class UnitBase : MonoBehaviour 
{
    public StateMachine stateMachine { get; private set; }
    public IdleState IdleState { get; private set; }
    public ChasingState ChasingState { get; private set; }
    public AttackState AttackState { get; private set; }

    protected virtual void Awake() 
    {
        stateMachine = new StateMachine();
        IdleState = new IdleState(this);
        ChasingState = new ChasingState(this);
        AttackState = new AttackState(this);
    }
}

2. 상태 인터페이스: IState

  • 모든 상태 클래스들이 구현하는 인터페이스입니다.
public interface IState 
{
    void Enter();
    void Update();
    void Exit();
}

3. 각 상태 클래스

타겟이 감지되면 ChasingState로 전이

IdleState

public void Update() 
{
    if (unit.Target != null && unit.IsTargetInRange(unit.unitStat.chaseRange)) 
    {
        unit.stateMachine.ChangeState(unit.ChasingState);
    }
}

ChasingState

  • 타겟을 향해 이동
  • 공격 사거리 내에 들어오면 AttackState로 전이
public void Update() 
{
    unit.Agent.SetDestination(unit.Target.position);

    if (unit.IsTargetInRange(unit.unitStat.attackRange)) 
    {
        unit.stateMachine.ChangeState(unit.AttackState);
    }
}

AttackState

  • 일정한 공격 쿨타임을 기반으로 애니메이션 호출 (Animation Event로 Attack 호출)
  • 타겟이 사거리 밖이면 다시 IdleState로 전이
public void Update() 
{
    if (Time.time - lastAttackTime >= attackCooldown) 
    {
        unit.Attack();
        lastAttackTime = Time.time;
    }
}

📃 상태 전이 관리: StateMachine

상태 간 전이를 처리(Enter, Exit)하며 현재 상태의 Update()를 매 프레임 호출합니다.

public class StateMachine 
{
    private IState currentState;

    public void ChangeState(IState newState) 
    {
        currentState?.Exit();
        currentState = newState;
        currentState.Enter();
    }

    public void Update() 
    {
        currentState?.Update();
    }
}

정리

  • 플레이어도 자동으로 적을 찾아 이동하므로 몬스터와 공통된 로직 UnitBase 클래스로 묶어서 처리
  • 상태 패턴은 각 상태를 클래스로 분리함으로써 코드 가독성유지보수성을 높여줍니다.
  • FSM 구조는 AI 행동 전이를 깔끔하게 구현할 수 있어, 몬스터나 NPC 행동 설계에 매우 유용
  • UnitBase에 공통 로직을 묶고, FSM은 상태 전이만 관리하도록 책임 분리가 잘 되어 있어 확장에 용이
  • AttackState에선 쿨타임 계산을 통해 프레임마다 공격하지 않도록 조절 가능
profile
Unity, C#

0개의 댓글