- Home /
Get animation clip length using Animator?
I am working on a script that discreetly plays animation states, and that part is working. However I also need to get the length of the current clip but haven't found a way to do it.
Here's the code I'm using:
Animator anim = obj.GetComponent<Animator>();
if(anim != null) {
anim.Play(track, -1);
AnimatorStateInfo info = anim.GetCurrentAnimatorStateInfo(0);
length = info.length;
Debug.Log("Animation("+track+") :"+length);
AnimationInfo[] clips = anim.GetCurrentAnimationClipState(0);
Debug.Log("clips:"+clips.Length);
foreach(AnimationInfo i in clips) {
Debug.Log(i.clip.name+":"+i.clip.length);
}
}
The animation is playing fine, but the length from AnimatorStateInfo is 0, and AnimationInfo count is 0, both of which are incorrect. My Animator controller has 3 states. I have also tried the 'GetNext' versions of these methods with the same results.
Anybody know how to get the length of the specified clip at runtime?
Answer by Steven-Walker · Apr 23, 2014 at 04:44 PM
EDIT: Found it! Turns out that the Motion type is derived from AnimationClip, so all that's required is a simple cast:
Animator anim = obj.GetComponent<Animator>();
if(anim != null) {
UnityEditorInternal.AnimatorController ac = anim.runtimeAnimatorController as UnityEditorInternal.AnimatorController;
UnityEditorInternal.StateMachine sm = ac.GetLayer(0).stateMachine;
for(int i = 0; i < sm.stateCount; i++) {
UnityEditorInternal.State state = sm.GetState(i);
if(state.uniqueName == track) {
AnimationClip clip = state.GetMotion() as AnimationClip;
if(clip != null) {
length = clip.length;
}
}
}
Debug.Log("Animation:"+track+":"+length);
}
Note also that the UnityEditorInternal object cannot be used in runtime code outside of the editor, so there is still no way to my knowledge of obtaining the AnimationClip at runtime from an Animator state. More explained here: http://forum.unity3d.com/threads/242478-Reading-keyframe-curve-data-from-Animator
The way the abstraction/black boxing of the Animator/$$anonymous$$ecanim system is set up is absolutely horrendous.
Answer by Jesus-Perez-Felipe · May 04, 2015 at 11:10 PM
Using UnityEditorInternal.AnimatorController just work in Unity editor, for runtime I do like this:
Animator anim = obj.GetComponent<Animator>();
float time;
RuntimeAnimatorController ac = anim[0].runtimeAnimatorController; //Get Animator controller
for(int i = 0; i<ac.animationClips.Length; i++) //For all animations
{
if(ac.animationClips[i].name == "AnimationName") //If it has the same name as your clip
{
time = ac.animationClips[i].length;
}
}
RuntimeAnimatorController ac = anim[0].runtimeAnimatorController;
Why anim is table ([0]) ?
It's a collection because there could be more than one animator attached.
Thank you Felipe, I used this as a linq way. float time = anim.runtimeAnimatorController.animationClips.First(x => x.name == "AnimationName").length;
Answer by EvilWarren · Apr 23, 2015 at 12:05 PM
Exactly one year late to answer this question, so might be of little use now.
The current clip being played's length can be read, in your case, using anim.GetCurrentAnimationClipState(0).length
with one caveat - it has to be done in the next frame. Not much info on it but probably due to execution order of animation update.
http://docs.unity3d.com/Manual/ExecutionOrder.html
I use a coroutine and wait for the end of frame. Just as an example:
IEnumerator ShowCurrentClipLength()
{
yield return new WaitForEndOfFrame();
print("current clip length = " + anim.GetCurrentAnimatorStateInfo(0).length);
}
3 and a half years later, your answer is the best I found. The caveat you give is very important! WaitForEndOfFrame fixed my bug.
Answer by belva1234 · Feb 16, 2018 at 11:26 AM
this will do the trick
Animator anim = GetComponent<Animator>();
float AnimationLength(string name) {
float time = 0;
RuntimeAnimatorController ac = anim.runtimeAnimatorController;
for (int i = 0; i < ac.animationClips.Length; i++)
if (ac.animationClips[i].name == name)
time = ac.animationClips[i].length;
return time;
}
Answer by cyborgjinx · Mar 27, 2018 at 02:22 PM
Animator animComp = GetComponent<Animator>();
animComp..GetCurrentAnimatorStateInfo(0).length;
Your answer
