Hi, I'm developing a 2d game heavily using the "new" animation system (Animator Controller -> not legacy). While the whole animator stuff is really helpful in some situations, it really misses one key feature for advanced scripting (or maybe I' wrong?): How can you wait for an animation to finish via scripting ? There are a couple of ways I could think of but which do not work in my situation: - Put the animation as a class attribute via editor into the script (Bad, because no loose coupling) - Put the length of the animation in the class via editor and do coroutine waiting (Bad, because time varies between animations) - Use GetCurrentAnimationState (Bad, because a) after you played an animation using Animator.Play() the current animation state might be unchanged four a couple of frames, b) if the animation is really short, the script might not notice the change and stalls forever) ----> Why the hell does Animator not expose an array of all animations ? This way I could simply get the length of an animation, play the animation while waiting via coroutines and continue... Why is the old system legacy while the new does allow fewer features ? You cant reduce features and call this improvements. So please, am I totally wrong and miss something or do i really need one of those upper 3 (bad) options ? Thanks in advance! Chris
Mecanim just has a different approach, but with 4.3+ you can do almost everything that you could do in Legacy (and of course much more). What about adding an animation event? BTW, Animator.GetCurrentAnimationClipState() returns an array of AnimationInfo[], which is a struct of AnimationClips and weight. So you can get the array of animations for the current state. But if I were to go this route I would use Animator.GetCurrentAnimatorStateInfo(). As soon as you change states (as long as it's a different state), you're guaranteed that it will return different info, so your coroutine knows to stop.
Hi Chris, Like TonyLi said, the best way to handle this is with AnimationEvent. Simply add an AnimationEvent at the end of your clip, this event will call a predefine function that you will provide when the clip finish to play. In the next release of Unity 5.0 you will have another way to handle this with a script that you will put on your state This new feature is called StateMachineBehavior. which can handle a few predefine callback message StateMachineBehaviour.OnStateEnter() StateMachineBehaviour.OnStateExit() StateMachineBehaviour.OnStateUpdate() StateMachineBehaviour.OnAnimatorMove() StateMachineBehaviour.OnAnimatorIK()
Thanks guys! Very good to know that unity5 will help! I can't wait for it, not just because the animation stuff Well I guess I'll try the StateInfo route again, AnimationEvents are nice but I want to trigger with my script arbitrary animations from different GameObjects in one Script. For more context: I doing one of those old pixel style games (ala Monkey Island or Indiana Jones) and I'm working on a conversation script between two people. The script gets an array of strings which start either with A:<text from A> or B:<text from B> or #A:<animation name of A> #B:<animation name of B> So I can use the same script and just change text and animation names. But, of course, I have to know when the triggered animation has completed so the conversation can go on... But I don't actually want the animations to be aware of this script so AnimationEvents wont fit in this scenario.. But again thank! Cheers, Chris
So, tested it again, and it GetCurrentAnimationStateInfo() does return a different state after changing: var currentAnimator = partner.GetComponent<Animator> (); currentAnimator.Play (StateName); Debug.Log (currentAnimator.GetCurrentAnimatorStateInfo (0).IsName(StateName)); // False!! So the state does not change immediately. When I add a yield return new WaitForFixedUpdate() or something like that the state is correct. But I would trust this behavior, so I'm pretty much out of luck here I guess...
It is expected in this case, when you call Animator.Play, the animator must be ticked by the game engine first before you will see any change.
Here: http://forum.unity3d.com/threads/effective-2d-animation-with-mecanim-sample-code-inside.250552/ I provide a 2D animator "bridge" which moves between a set of events and an animation state. In doing this I I include the ability to prioritise animations such that a higher priority one-shot animation will run to completion before a lower priority one starts. Have a look at the code it might be of use.