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
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
No Comments