[Unity] State Pattern

AsiaticRicecake·2025년 5월 26일

1. 📖 State Pattern

상태 패턴은 객체의 상태에 따라 행동을 다르게 해야 할 때 사용하는 디자인 패턴입니다.

객체가 가진 상태를 관리하고, 각 상태에 따른 행동을 미리 지정할 수 있습니다.

예를 들어봅시다.

플레이어 상태는 Idle, Run, Jump, Attack, Die 이런 식으로 있을 것이고,
몬스터 상태는 Patrol, Chase, Attack이 있을 것이고,
문 상태는 Open, Close, Locked가 있을 것이고,
게임 진행 상태는 Title, Playing, Paused, GameOver가 있을 것입니다.

간단한 게임이면 몰라도 이런 식으로 여러가지 상태가 있을 때
한 코드에 다 집어 넣어서 관리한다면 유지 보수하기가 상당히 까다롭겠죠...
또 상태마다 행동 분리하면 조건문이 남발될 수 있어 아도겐 코드가 될 수도 있습니다.

1-1. 🖥️ 상태 패턴 몬스터 예시

만약 몬스터가 Patrol, Chase 두 가지 상태를 가진다는 가정 하에 예시를 보겠습니다.

public interface IMonsterState
{
    public void Enter(Monster monster);
    public void Execute(Monster monster);
    public void Exit(Monster monster);
}

보통 먼저 이런 식으로 인터페이스를 선언합니다.
공통점이 많다면 추상 클래스를 사용해도 무방합니다.

public class PatrolState : IMonsterState
{
    public void Enter(Monster monster)
    {
        Debug.Log("패트롤 상태 진입");
    }

    public void Execute(Monster monster)
    {
		Debug.Log("패트롤");
    }

    public void Exit(Monster monster)
    {
        Debug.Log("패트롤 상태 종료");
    }
}
public class ChaseState : IMonsterState
{
    public void Enter(Monster monster)
    {
        Debug.Log("추격 상태 진입");
    }

    public void Execute(Monster monster)
    {
     	Debug.Log("플레이어 추격");
    }

    public void Exit(Monster monster)
    {
        Debug.Log("추격 상태 종료");
    }
}

이런 식으로 상태에 나누어서 코드를 만드는 디자인 패턴입니다.

여기서 사용하실 때 주의하셔야 할 점이 있습니다. 남발하듯이 상태를 나누시면 안됩니다.
상태를 분리했지만 상태 간 로직 차이가 거의 없으면 괜히 유지보수하기만 힘들 뿐입니다.

public class SlowMoveState : IMonsterState
{
    public void Enter(Monster monster)
    {
        Debug.Log("천천히 움직임 상태 진입");
    }

    public void Execute(Monster monster)
    {
		Debug.Log("움직임");
    }

    public void Exit(Monster monster)
    {
        Debug.Log("천천히 움직임 상태 종료");
    }
}
public class FastMoveState : IMonsterState
{
    public void Enter(Monster monster)
    {
        Debug.Log("빠른 움직임 상태 진입");
    }

    public void Execute(Monster monster)
    {
		Debug.Log("움직임");
    }

    public void Exit(Monster monster)
    {
        Debug.Log("빠른 움직임 상태 종료");
    }
}

보시면 로직이 동일하죠? 많이 과장된 예시이기는 합니다만...
이러한 경우에는 굳이 상태 패턴을 써서 나눌 필요가 없는 것입니다.

0개의 댓글