Search Unity

Is there a 'ThisAnimFinished' function?

Discussion in 'Animation' started by mr_blahblah, Jun 26, 2016.

  1. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    That, or a simple way to call a oneshot anim and get a callback/be able to call an event when that anim ends.

    I like the idea of the Mecanim system, but without support for simple functions like this, it's incomplete.
     
  2. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    Basically, I need a deterministic way to tell when animation has finished playing. That's it. Does that exist?
     
  3. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    *bump* I've read a dozen threads looking for similar functionality - is it planned, does it exist, is there a simple way to do achieve this?
     
  4. TrickyHandz

    TrickyHandz

    Joined:
    Jul 23, 2010
    Posts:
    194
    There are a couple of ways to approach this with Mecanim. You could use AnimationEvents set up on the last frame of the animation or you could use a StateMachineBehaviour and use the OnStateExit() callback to perform an action.

    Hope that helps you out.
     
  5. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    Thanks, but that doesn't help.

    OnStateExit isn't firing for me reliably (sometimes it does, sometimes it doesn't).

    I've also tried AnimationEvents (fighting the unity UI to do so), but they *also* don't fire sometimes - I've read a theory that they can be skipped if there's a frameskip (presumably, that's what's happening to me).
     
  6. TrickyHandz

    TrickyHandz

    Joined:
    Jul 23, 2010
    Posts:
    194
    Out of curiosity, are you animating something to move off screen? If you are making something move out of the viewport, Unity might be culling the animation and subsequently stopping the animation from completing, state from updating and event from firing. In the past, I can remember having to make sure I set the Animator Culling Mode on a UI's Animator to "Always Animate" to get OnStateExit() and/or end frame events to fire consistently. I'm just spit balling here, so I apologize if that isn't applicable.
     
  7. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,938
    The problem here is when you are transitioning with a mecanim state, there is no way to tell if the transition is ending or the animation you are transitioning to is ending. Therefore you will probably want to look at the time of the state.

    Assuming anim is a cached Animator:

    To get the normalized time (0 = start, 1 = finish) of the current state, you can use this:
    Code (CSharp):
    1. AnimatorStateInfo currentState = anim.GetCurrentAnimatorStateInfo(0);
    2. float playbackTime = currentState.normalizedTime;
    To see if it is currently transitioning you can use this:
    Code (CSharp):
    1. anim.IsInTransition(0);
    Using both allows you to figure out a decent check condition without callbacks or animation events.
     
    theANMATOR2b and TrickyHandz like this.
  8. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    Thanks for the tip, but I tried that already - no luck =|


    Thanks hippocoder, I'll try that. I'm utterly disappointed in Unity that a technique like this is required - quite shocked really. I'll report back...

    EDIT: does this imply I need to use layers to be able to check when a particular animation/state is finished? I'm trying to keep things simple, and would prefer not to add layers unless it's absolutely neccessary.
     
    Last edited: Jul 1, 2016
  9. mr_blahblah

    mr_blahblah

    Joined:
    Jan 15, 2016
    Posts:
    25
    Hippocoder, that method basically worked - I tried the following:

    1. AnimatorStateInfo currentState = anim.GetCurrentAnimatorStateInfo(0);
    2. float playbackTime = currentState.normalizedTime;

    3. if (currentState.IsName("Attack") && anim.IsInTransition(0))
    4. { //something }
    5. Debug.Log("Seriously unity? I'm switching to Unreal first chance I get");
    6. }

    And for the first time in about 2 days, I got that log message to fire. I'd tried everything using the built-in systems I could find (Mecanim stuff, SMBs, Animation events), and this is what worked.

    To any Unity devs reading this - I'm shocked and dismayed that Unity doesn't have reliable functionality for firing events when Animations finish. OnAnimationComplete. Seriously.

    I'm glad this method worked, but this feels like a hack - and honestly, considering the amount of effort that's clearly gone into building the mecanim system, the animator system and timeline interface, etc, I would not recommend Unity to anybody at this point.

    Certainly the only reason I've persisted is that I've spent a month working in more productive areas of the engine, and my time is limited, so I persisted.

    EDIT: this issue meant I missed a deadline. If I'm lucky enough to have my project still considered for the funding I'm going for, I will ditch Unity in favour of something else, and advocate strongly against using it. I'm no stranger to game engines, but there should be a big red warning over the Animation/Animator systems - they're either broken through negligence, or broken by design.
     
  10. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,938
    Hi,

    Yeah I had to work this out for myself. The problem is there can't really be an api call for it as states are constantly "in between" something. In this case you want to check if it's not currently transitioning, and then check if the time is >1, which means for a simple "check if this is finished" with no exit state, it will work :)

    It's a hard task to make commands for, but the tools are there for us to work with - just it's a little more involved than a simple "is this done" command, because it can do many different things, for example someone might be using it to play one shot anims, or someone might be using it as a blueprint/playmaker replacement (yes it can do that, surprisingly) ... it's pretty flexible.
     
    theANMATOR2b likes this.