Skip to main content

Preventing AnimationEvent during State Transition by not using State Machine Behavior

✍ Last Updated : September 22, 2022

The 2nd alternative for animation event handling works by setting and checking the state manually.

Case example :

AttackStart Event must be called, but AttackCheck must not get called since the Attack State is already in transition

AttackStart Event must be called, but AttackCheck must not get called since the Attack State is already in transition

First, prepare the animationEvent listeners

public class AnimationEventHandler : MonoBehaviour
{
        [HideInInspector] public UnityEvent<object> onAttackStart;
        [HideInInspector] public UnityEvent<object> onAttackCheck;
        [HideInInspector] public UnityEvent<object> onAttackEnd;

        void AttackStart() => onAttackStart?.Invoke();
        void AttackCheck() => onAttackCheck?.Invoke();
        void AttackEnd() => onAttackEnd?.Invoke();
}

Then in the state handler, set state according to triggered event. In this case state = Attacking

public class StateHandler : MonoBehaviour
{
				System.Action state;

				void Awake()
        {
						animationEventHandler = GetComponent<AnimationEventDirectHandler>();
						animationEventHandler.onAttackStart.AddListener(() => OnAttackStart());
						animationEventHandler.onAttackEnd.AddListener(() => OnAttackEnd());
				}
				...
				public System.Action state { get; private set; }
				void OnAttackStart()
        {
            state = Attacking;
        }

        void OnAttackEnd()
        {
            state = Idling;
        }

				public void Attacking()
        {

        }

        public void Idling()
        {

        }
				...
}

Then in the action handler, when OnAttackCheck is triggered, manually check if state is Attacking or not

public class ActionHandler : MonoBehaviour
{
				...
				void Awake()
        {
            stateHandler = GetComponent<StateHandler>();
						animationEventHandler = GetComponent<AnimationEventDirectHandler>();
						animationEventHandler.onAttackCheck.AddListener(() => OnAttackCheck());
				}

				void OnAttackCheck()
        {
            if (stateHandler.state == stateHandler.Attacking)
            {
                hitBox.gameObject.SetActive(true);
                StartCoroutine(DisableHitBox());
            }
        }
				...
}

Pros :

  • No need for adding state machine behavior scripts

Cons :

  • Script might overlaps with gameplay script
  • More context-sensitive, not flexible