[Unity] FSM_원리 (State)

Learning 

When: 1학년 9월 19일

 

How:

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

 

Understanding:

State (Enemy)

using UnityEngine;

public abstract class EnemyState
{
    protected Animator animator;
    protected readonly int myHash;
    protected Enemy enemy;

    public EnemyState(Animator animator, string myHash, Enemy enemy)
    {
        this.animator = animator;
        this.myHash = Animator.StringToHash(myHash);
        this.enemy = enemy;
    }

    protected virtual void Enter()
    {
        animator.SetBool(myHash, true); // 모든 상태는 모두 자신의 애니메이션을 실행하기
        //때문에 부모에 이런 코드를 넣어도 상관없습니다.
    }

    protected virtual void UpdateState()
    {

    }

    protected virtual void Exit()
    {
        animator.SetBool(myHash, false);
    }
}
  • 설명 : FSM의 S가 state인데, 자식들(AttackState, ChaseState, IdleState 등)이
    EnemyState를 상속받아 Enter와 UpdateState, Exit를 각각 구현합니다. 예를 들어 IdleState는
    Enter(상태에 진입했을 때 처음 한번 실행)에서 base.Enter를 하여 자신의 애니메이션을 실행하고
    속도를 0으로 만듭니다. 그리고 UpdateState(상태에 진입하면 매 프레임마다 실행)에서는
    계속 플레이어가 주위에 있지는 않은지 감지하고, 플레이어가 추격 범위 안에 들어오면
    ChaseState로 상태를 전이합니다. 마지막으로 Exit(상태가 전이될 때 원래 상태가 마지막으로 실행할 일)에서는
    base.Exit()를 실행하여 애니메이터에서 자신의 state를 끕니다.
    여기에 있는 Enter, UpdateState, Exit 등의 메서드는 StateMachine에서 실행해 줍니다.
    Rigidbody를 건드리거나 플레이어를 감지하는 등의 행동을 전부 이 코드에서 하면 복잡해지기 때문에
    중간 다리 역할을 할 Monobehaviour를 상속받는 Enemy 객체도 생성자에서 받으면 좋습니다.
  • 예시)
    • IdleState
using UnityEngine;

public class EnemyIdleState : EnemyState
{
    private float currentTime;
    private float checkTime = 0.3f;   

    public EnemyIdleState(Enemy enemy, EnemyStateMachine stateMachine, string animName) : base(enemy, stateMachine, animName)
    {
    }

    public override void Enter()
    {
        base.Enter();
        enemy.MoveCompo.SetXMove(0f);
    }

    public override void UpdateState()
    {
        base.UpdateState();

        currentTime += Time.deltaTime;

        if (currentTime >= checkTime)
        {
            if (enemy.CheckChaseRange())
            {
                stateMachine.ChangeState(EnemyEnum.Chase);
            }

            currentTime = 0;
        }
    }

    public override void Exit()
    {
        base.Exit();
    }
}

 

Result: State는 특정 상태에서 그 오브젝트가 해야 할 일들을 들어올 때, 들어왔을 때, 나갈 때로 나누어서 정의하고, StateMachine에서 실행시키는 방식으로 작동합니다.

'UnityEngine' 카테고리의 다른 글

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