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?
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.
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:
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.
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.
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);
}