[Unity] FSM_원리 (StateMachine)

Learning 

When: 1학년 9월 19일

 

How:

원래 개념만 알고 있을 때는 써야 하는 이유, 어떻게 쓰는지에 대해 이해가 되질 않았는데, 수업 시간에 FSM을 이용하여 코드를 직접 짜보니 이해가 돼서 복습 겸 공부하게 되었습니다.

 

Understanding:

StateMachine (Enemy)

using System.Collections.Generic;

public enum EnemyEnum
{
    Idle,
    Chase,
    Attack,
    Patrol,
    Hit
}
public class EnemyStateMachine
{
    private Dictionary<EnemyEnum, EnemyState> enemyStateDictionary = new();
    
    public EnemyState CurrentState { get; private set; }

    public void AddState(EnemyEnum enemyEnum, EnemyState state)
    {
        enemyStateDictionary[enemyEnum] = state;
    }

    public void ChangeState(EnemyEnum enemyEnum)
    {
        if (CurrentState != null)
        {
            CurrentState.Exit();
        }
        CurrentState = enemyStateDictionary[enemyEnum];
        CurrentState.Enter();
    }

    public void Initialized(EnemyEnum enemyEnum)
    {
        CurrentState = enemyStateDictionary[enemyEnum];
        CurrentState.Enter();
    }
}
  • 설명 : StateMachine은 FSMManager로 불러도 될 만큼 FSM에서 중요한 역할을 맡고 있습니다.
    이 글에 나와 있지만 상태를 저장, 전이, 초기화 등의 일을 합니다. state는 enum 키워드
    알아보기 쉽게 변환할 수 있는데, 딕셔너리의 키 값을 EnemyEnum이라는 enum값으로 하고,
    값을 state 클래스의 인스턴스로 하여 현재 상태가 EnemyEnum이가 Idle이라면
    딕셔너리의 Idle를 키로 하는 값, 즉 인스턴스의 UpdateState() 메서드를 계속 실행시키는 방식으로 FSM이 돌아갑니다.
    코드를 설명 드리자면 enemyStateDictionary라는 딕셔너리로 State를 저장하고,
    Brain에서 EnemyStateMachine를 생성하여 객체를 만든 다음(StateMachine은 Monobehaviour가 아닌
    일반 클래스이기 때문에 컴포넌트로 붙이지 않고 생성자로 생성해 주어야 합니다. EnemyState도 마찬가지입니다.)
    AddState() 메서드를 EnemyEnum.Attack, new EnemyAttackState() 와 같이
    enum 값과 EnemyState 객체를 인수로 주어 딕셔너리에 저장시킵니다. 그리고 Initialized() 메서드로
    EnemyEnum.Idle과 같은 시작할 때의 상태를 정해줄 수 있습니다. 그리고 예를 들어
    EnemyIdleState 객체의 UpdateState 메서드를 실행하던 중 플레이어가 쫓는 범위 안에 들어왔다면
    ChangeState(EnemyEnum.Chase)와 같이 ChangeState() 메서드를 사용하여 상태를 전이할 수 있습니다.

 

Result: Brain은 처음 Initialized() 메서드와 계속 StateMachine의 CurrentState의 UpdateState를 매 프레임 호출하는 것 외에는 딱히 하는 일이 없어 따로 적지 않았는데, 이런 구조로 FSM이 작동합니다. Unity에선 클래스의 생성자를 사용해 직접 인스턴스를 생성할 일이 거의 없었는데 StateMachine이나 State는 딱히 Monobehaviour로 Update나 Start를 사용할 필요가 없기 때문에 이런 저장고 같은 클래스를 컴포넌트로 붙이지 않고 직접 관리하는 것이 성능 면에서도 좋을 것 같아 잘 활용해야겠다는 생각이 들었습니다.

'UnityEngine' 카테고리의 다른 글

[Unity] 모노싱글톤 (MonoSingleton)  (0) 2025.10.22
[Unity] FSM_원리 (State)  (0) 2025.09.19
[Unity] FSM_개념  (0) 2025.09.18
[Unity] UnityEvent  (0) 2025.09.17
[Unity] UI 선택 판정 버그  (0) 2025.09.12