Wait until an animation is finished

I’ve searched for a while but haven’t found a proper solution yet.
First: I had an animation of 48 frames length and I needed to do some stuffs exacly when this animation ends, so in my coroutine I wrote this:

yield return new WaitForSeconds(0.8f);

It worked perfectly fine. However, using such exact number doesn’t seem right to me. The result might be different in other systems? I don’t even know. So I tried:

yield return new WaitForSeconds(MyAnim.GetCurrentAnimatorStateInfo(0).normalizedTime);

It didn’t work as expected. Did I use it wrong? What other ways do you guys suggest?
Second: Are GetCurrentAnimatorStateInfo() and GetCurrentAnimatorClipInfo() the same?

You can maybe just add an event at the end of your animation?
https://docs.unity3d.com/Manual/animeditor-AnimationEvents.html

1 Like

I second what LiLfire said. Animation Events are awesome, and pretty easy to use.

Also, you’re right. Generally hardcoding (coding exact numerical values) is generally a bad idea, as system functionality may vary. You’d be better of making it a variable.

In this case though, I’d go with an animation event too.

Never heard of Animation Events before, I’ll check it out right away, thanks guys :slight_smile:

I second the advice about using animation events. That being said, it might be interesting to know why your coroutine didn’t work.

.normalizedTime is the current time of the animation, normalized between 0 and 1. So if your clip is 5 seconds long, and the playback is at 1 second, .normalizedTime will be 0.2.

To get the duration of the current clip, you have to do this horrendous thing:

AnimatorClipInfo[] clipInfos = MyAnim.GetCurrentAnimatorClipInfo(0);
AnimationClip firstClip = clipInfos[0].clip;
float duration = firstClip.duration;

It returns an array in case the state is a blend tree, in which case there’s a bunch of different clips being played. Also note that if your transition isn’t instant, the clip infos will return the clips on the state you’re transitioning from until the transition has passed 50%. Or at least, that’s when I believe that the infos will change - afaik it’s not documented.

As you can see, the Animator is directly hostile towards the idea of building logic around information about the clips. So animation events is definitely the way to go.

1 Like

That’s very interesting. So I guess it would be quite complicated if I went with the Animator in this case, glad to know there’s something like Animation Events. But new things are always welcome, thanks a lot, Baste.

Besides checking duration and using animation events, a variant is to check the animation normalized time.

I picked the solution from How can I check if an animation is playing or has finished? (Using Animator/C#) - Questions & Answers - Unity Discussions and adapted it into a coroutine. Example:

public IEnumerator PlayAnimationCoroutine(int value)
{
    m_Animator.SetInteger(/* put your hash here */, value);
  
    // Wait one frame to let the animator enter the next animation first
    yield return null;
  
    // From here, wait for the new animation to finish
    // - animation must be on first layer
    // - animation must have 0 transition time, else we must also check !m_Animator.IsInTransition(0)
    // https://answers.unity.com/questions/362629/how-can-i-check-if-an-animation-is-being-played-or.html
    yield return new WaitUntil(() => m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f);
}
2 Likes