Tiny Star
본문 바로가기
Project/Unity Bootcamp 13th

[오버워치 디펜스 모바일] | #3 유니티 State Machine Behaviours

by 별터 2025. 7. 1.

오늘은 몬스터 좀닉의 애니메이션을 좀닉의 상태에 따라 변화하도록 만들어주겠다.

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

 

어제, 가볍게 좀닉의 상태를 enum 으로 만들어 좀닉이 거점에 도착하면 pool 에 반납되도록 설정했었다.

 

using System;
using System.Collections;

public enum ZomnicState
{
    Idle,
    Move,
    SelfDestruct,
    Dead,
    Hit
}

public class ZomnicController : MonoBehaviour
{
    [SerializeField] private Zomnic zomnic;
    [SerializeField] private Vector3 basePoint;

    private ZomnicState _zomnicState = ZomnicState.Idle;
    private ZomnicPoolManager _zomnicPoolManager;
    private float _reachTimer = 0f;
    private bool _reachBasePoint = false;

    public void InjectPoolManager(ZomnicPoolManager poolManager)
    {
        _zomnicPoolManager = poolManager;
    }

    private void Update()
    {
        switch(_zomnicState)
        {
            case ZomnicState.Idle:
                ZomnicIdle();
                break;
            case ZomnicState.Move:
                ZomnicMove();
                break;
            case ZomnicState.SelfDestruct:
                ZomnicSelfDestruct();
                break;
            case ZomnicState.Dead:
                ZomnicDead();
                break;
            case ZomnicState.Hit:
                ZomnicHit();
                break;
        }

        if (zomnic.HP <= 0)
        {
            _zomnicState = ZomnicState.Dead;
        }

        float distance = Vector3.Distance(transform.position, basePoint);
        if (distance < 1)
        {
            _reachBasePoint = true;
            Debug.Log("ľľÂřÇÔ");
        }

        if (_reachBasePoint == false)
            return;

        _reachTimer += Time.deltaTime;

        if (_zomnicState == ZomnicState.SelfDestruct)
            return;

        if (_reachTimer > 2f)
        {
            _zomnicState = ZomnicState.SelfDestruct;
            _reachTimer = 0;
        }
    }

    
    private void ZomnicIdle()
    {
        // TODO : Write Animation Code
        Debug.Log("Idle");
        if (gameObject.activeSelf == true)
            _zomnicState = ZomnicState.Move;
    }

    private void ZomnicMove()
    {
        // TODO : Write Animation Code
    }

    private void ZomnicSelfDestruct()
    {
        // TODO : Write Animation Code
        Debug.Log("SelfDestruct");
        _zomnicPoolManager.ReturnZomnic(gameObject);

    }

    private void ZomnicDead()
    {
        Debug.Log("Dead");
        _zomnicPoolManager.ReturnZomnic(gameObject);
    }
    private void ZomnicHit()
    {
        // TODO : Write Animation Code
    }
}

어제의 코드는 이러한데, 오늘은 State Machine Behaviours 를 상속 받아 만들어 보려고 한다.

이렇게 animator 창에서 상태를 선택한 후, 스크립트를 만들면

이렇게 StateMachineBehaviour 를 상속받은 스크립트가 만들어지게 된다.

위와 같은 방식으로 만들거나 아니면 기본 C# 스크립트에 StateMachineBehaviour 를 상속받으면 된다.

< 메서드 >

OnStateEnter 상태(State) 진입 시 호출
초기화 로직, 파티클 / 이펙트 시작, 사운드 재생, 변수 리셋 등을 구현
OnStateUpdate 상태(State) 머무르는 동안 매 프레임 호출
이동 처리, 타겟 추적, 상태 지속 효과 (파티클 갱신 등) 등을 구현
OnStateExit 상태(State) 를 벗어날 때 호출
이펙트 종료, 변수 정리, 다음 상태 준비 등의 정리 로직 구현
EnterLogic OnStateEnter 내부에서 호출하는 메서드
진입 로직을 구체적으로 작성
UpdateLogic OnStateUpdate 내부에서 호출하는 메서드
매 프레임 반복 로직을 작성
OnStateExit OnStateExit 내부에서 호출하는 메서드
종료 로직을 작성

 

저는 우선 이동 로직이나 다른 로직에서는 자세히 구현할 것이 없고 죽음 애니메이션이 끝난 후 반납로직만 작성하면 되므로, 

ZomnicDead 스크립트를 만들어서 밑과 같이 작성했습니다.

using UnityEngine;

public class ZomnicDead : StateMachineBehaviour
{
    // OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
    //override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
    //override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    
    //}

    // OnStateExit is called when a transition ends and the state machine finishes evaluating this state
    override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        ZomnicPoolManager zomnicPoolManager = animator.GetComponent<Zomnic>().ZomnicPoolManager;
        GameObject zomnic = animator.gameObject;

        zomnicPoolManager.ReturnZomnic(zomnic);
    }

    // OnStateMove is called right after Animator.OnAnimatorMove()
    //override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that processes and affects root motion
    //}

    // OnStateIK is called right after Animator.OnAnimatorIK()
    //override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    //{
    //    // Implement code that sets up animation IK (inverse kinematics)
    //}
}

 

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

이러면 좀닉이 거점에 도착했을 때 부들대다가 사라지는 것 까지 완료!!

사라지는 건 ZomnicDead.cs 에서만 수정한 겁니다.

 

어찌저찌 괜찮아보이네요..

이제 플레이어 구현할 때 잘 사용해야겠어요