Is there a 'ThisAnimFinished' function?

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.

Basically, I need a deterministic way to tell when animation has finished playing. That’s it. Does that exist?

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?

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.

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).

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.

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:

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

To see if it is currently transitioning you can use this:

anim.IsInTransition(0);

Using both allows you to figure out a decent check condition without callbacks or animation events.

2 Likes

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.

Hippocoder, that method basically worked - I tried the following:

  • AnimatorStateInfo currentState = anim.GetCurrentAnimatorStateInfo(0);
  • float playbackTime = currentState.normalizedTime;
    • if (currentState.IsName(“Attack”) && anim.IsInTransition(0))
  • { //something }
  • Debug.Log(“Seriously unity? I’m switching to Unreal first chance I get”);
  • }

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.

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 :slight_smile:

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.

1 Like