Animation events not firing

I’m having a problem using animation events for a looping 2D sprite animation. While the events usually fire, they don’t always fire.

For example, I have a sprite that fires “StartCombatAnimation()” on frame 1, and “EndCombatAnimation()” on the 2nd last frame. That end event fires only about 98% of the time. It fired even less when I had it on the last frame, which is why I moved it up a bit.

As I increase Time.timeScale (ie. say 5x normal time), it misses that event even more, leading me to believe that the frames are being skipped, and therefore the events are being skipped.

I’m looking for advice for a way to reliably force events to fire at the beginning, during, and/or at the end of an animation?

Related: I had this problem on events not firing on last frame of a single shot (i.e. not looping) animation. I could fix it by moving the event a few frames forward, but the engineer in me did not like the arbitrary nature and guessed it might be intermittent behavior due to framerate. So I kept digging until I found reliable behavior.

In my case, in the state machine, I had my animation state transitioning to Exit. Apparently this causes some kind of blending to happen (even though I have no other animations or layers in this case, and no explicit blending), which can skip over n number of frames at the end. I deleted the transition to Exit in Animator, and now my Event fires 100% of the time on the final frame.

So I’m guessing any kind of blending activation that occurs has the possibility to drop frames, and if there’s an AnimationEvent on a frame that’s dropped… guess what, that AnimationEvent doesn’t get triggered!

Hope that helps someone else!

This should be categorized as a bug, but judging from how old this issue is from the posts I have seen about it, I doubt it will be fixed as such. If it’s by design, it’s a poor choice to have the possibility of AnimationEvents getting missed due to blending… these should be guaranteed to hit.

public class CombatBehaviour : 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) {
      StartCombatAnimation();
    }

    // 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) {
        EndCombatAnimation();
    }
}

See Unity - Scripting API: StateMachineBehaviour for more. That behavior must be added as a component to animator state with your animation. That works 100 % of the time

I dont like relying too much on animation driven events just because they can sometimes hiccup like this. I’ve found its much easier to just make your own “control” over the events by using a coroutine.

I am guessing you are triggering the “StartCombatAnimation()” as an attack of some sort.

    private bool attacking = false;
	public float animLength = 1.5f; // adjust this to fit your attack animations length

	void Update ()
	{
		if(Input.GetButtonDown("Fire1") && !attacking )
		{
			Attack();
		}
	}
	
	void Attack(){
		attacking = true;
		//Trigger the animation here
		//Trigger the start animation events here
		StartCoroutine(Attacking());
	}
	
	IEnumerator Attacking(){
		yield return new WaitForSeconds(animLength );
		// trigger the stop animation events here
		attacking = false;
	}

To better understand why this is possibly happening it would require us to see the code that triggers your attacks. If you are crossfading or blending animations into one another its most likely the frame that triggers your event is getting cut out.

Deepscorn has the right idea with a StateMachineBehaviour script. I was about to create my own generic StateMachineBehaviour script, but found that the asset called “Animator Events” on the Asset Store did it already.

Just to recap why Animation Events are this unpredictable. If the frame is skipped, the Animation Event is skipped. Any lag or speeding up of a clip, will result in skipped frames and thus skipped Animation Events, making them completely useless. Get that asset. You won’t regret it. If you’re broke, write your own generic StateMachineBehaviour. It’s not too difficult to wrap your head around. I just don’t understand why Animation Events are this useless, when they have this system, as well.

Good luck, everyone.