Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Mecanim 'Wait for animation to complete" functionality

Discussion in 'Editor & General Support' started by yumupdate, Jul 11, 2013.

  1. yumupdate

    yumupdate

    Joined:
    Nov 20, 2012
    Posts:
    30
    I have a series of events that happen in my game using Coroutines. All of them work as expected except the "PlayOnce" helper function I've made that relies on the current animation state to provide it's normalized time (should be between 0.0 and 1.0, where 0 is the beginning and 1 is the end of the animation.) The idea is to yield until the animation is completed, then the sequence can continue. It pulls an animator's boolean high long enough to get the animation to start playing, then should play the animation to completion and pull the boolean low again.

    If I change the condition from 0.95f to 0.095f, most animation work, but some jitter as the loop repeats infinitely. At 0.95f, all animations jitter infinitely. Here's the code ...

    Code (csharp):
    1. public IEnumerator PlayOnce(Animator changedAnimator, string paramName)
    2. {
    3.     changedAnimator.SetBool(paramName, true);
    4.     yield return null;
    5.     while (PlayerController.currentAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime < 0.95f)
    6.     {
    7.         yield return null;
    8.     }
    9.     changedAnimator.SetBool(paramName, false);
    10. }
    Debug output of the normalizedTime value suggests that it makes it to ~0.01 - ~0.02 for most of the animations before it starts repeating constantly. And none of these animations are set to loop. And I'm not changing the normalized time anywhere. Simply checking it.

    Thanks!
     
  2. yumupdate

    yumupdate

    Joined:
    Nov 20, 2012
    Posts:
    30
    Experimentation proved useful here, as I was able to simply move line 9 (setting the boolean to false) above the while loop and now it works 100%. New code is:

    Code (csharp):
    1. public IEnumerator PlayOnce(Animator changedAnimator, string paramName)
    2. {
    3.     changedAnimator.SetBool(paramName, true);
    4.     yield return null;
    5.     changedAnimator.SetBool(paramName, false);
    6.     while (PlayerController.currentAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime < 0.95f)
    7.     {
    8.         yield return null;
    9.     }
    10. }
    Hope it helps someone.
     
  3. patrickt

    patrickt

    Joined:
    Mar 23, 2011
    Posts:
    21
    I believe in the latter case the while loop is probably unnecessary, you're turning your boolean on and then flipping it back off on the next call.

    This should cause the animation to play until completion once.
     
  4. yumupdate

    yumupdate

    Joined:
    Nov 20, 2012
    Posts:
    30
    While that is true, this function serves more purpose than just playing the animation all the way through. As I stated, I'm using it in a series of Coroutines, so they fire off one after the other. An event happens after the animation is completed as opposed to right after firing off the animation.