# Humanoid Retargetting: Number of frames in LateUpdate is not the same as frames in animation

I need to play an animation in such a way that each frame is for sure being played and not skipped.

Why? I want to transfer an animation from 1 model to another. One model is Humanoid, the other one is Generic. This way, I can "save out" the Humanoid retargetting and process it in an external animation editor later.

To transfer the animations, I need to make sure that I don't miss any frame while copying the pose to the other model.

To do that, I use a very slow animator speed like this:

_animator.speed = 0.01f;


The Unity editor says this about the animation:

To make sure that each frame is really shown / played, I have implemented my own counter. My counter however returns 43 frames and not 51 frames as the Inspector. No matter how often I repeat this process, it always return 43 frames.

What am I missing?

Thank you!

private void LateUpdate()
{

float f = _animator.GetCurrentAnimatorClipInfo(0)[0].clip.length * (_animator.GetCurrentAnimatorStateInfo(0).normalizedTime % 1) * _animator.GetCurrentAnimatorClipInfo(0)[0].clip.frameRate;
int iCurrentFrameIDInAnimationFile = (int)f;

bool bIsNewFrame = (iCurrentFrameIDInAnimationFile != _iLastFrameIDInAnimationFile);

if (!bIsNewFrame)
{
return;
}
else if (bIsNewFrame)
{
_iFrameCount += 1;
}

_iLastFrameIDInAnimationFile = iCurrentFrameIDInAnimationFile;

if (_animator.GetCurrentAnimatorStateInfo(0).normalizedTime > 1 && !_animator.IsInTransition(0))
{
//animation has finished playing
Debug.Log("Frames: " + _iFrameCount); //this returns 43 frames. Why???
}

• Are you sure that animation frames and render frames are related, i.e. isn't animation FPS just animation speed parameter unrelated to screen FPS? Apr 11, 2021 at 18:45
• @Nikaas Yes, it turned out that the problem was that Unity seems to require some time for the retargetting and skips some frames at first to keep a reasonable speed. Once it has retargetted the animation, it will be played as expected. Apr 25, 2021 at 20:01

I add a second answer since the first one is valid for others in similar situations.

Normally you don't have to calculate the frame rate as you do - since it can be done even without playing in my previous answer. However, you are trying to figure out why not all frames were playing once the animation is "done" so I think I understand what you are trying to do. Unless some other parts of your code interfere with the "_iFrameCount", it should be the same as the number of frames in your animation - unless (and here is probably the reason), your check at the end of the LateUpdate() is not doing what you expect.

if (_animator.GetCurrentAnimatorStateInfo(0).normalizedTime > 1 && !_animator.IsInTransition(0))
{
//animation has finished playing
Debug.Log("Frames: " + _iFrameCount); //this returns 43 frames. Why???
}


When normalizedTime is greater than 1, you have reached the end of the current animation, which can consist of several animation clips like this:

It is first when we reach the end of the second animation normalizedTime > 1. Then, of course, why is "_iFrameCount" less than you expect. Well, could be several reasons, for example, this:

Note that the two animations will finish, normalizedTime > 1, before the first animation has finished (if it had not been interrupted by the second animation).

The animator could also be interrupted by some other code/event.

• Thank you, but it's only 1 animation without transitions. I would tend to believe that the Humanoid retargetting does something unexpected. Apr 11, 2021 at 13:49
• In your picture, "Anim. Compression" is off and it is 51 frames, so I don't think it is the import settings. How is your Animator set up? Update Mode = Normal? Apr 11, 2021 at 14:37
• Yes, "Normal" and "Cull Update Transforms". Apr 11, 2021 at 14:40
• What is the "Clip Count" (at the bottom of the Animator)? Apr 11, 2021 at 14:43
• Clip Count says "1". Apr 11, 2021 at 14:46

In the chat, Anders I discussed the problem further, and he found out that Unity requires some warm up for the retargetting.

The first time around, it still misses frames.

After the first time (for playing of the animation), all works as expected.

To calculate the number of frames in an animation, simply multiply the animation time with the framerate.

    AnimationClip clip = _animator.GetCurrentAnimatorClipInfo(0)[0].clip;
float numberOfFrames = clip.length * clip.frameRate;


Your animation is 1.7 seconds long with a framerate of 30 which is 51 frames (1.7*30). The playback speed of the animator does not change this value.

The tricky part is that an animation consists of a lot of keyframes, and they don't have to be evenly distributed. If your keyframes are evenly distributed, that should not be a problem, but if not it gets harder. Here is a simple animation with sprites (21 frames). Note that each keyframe is five frames apart, except the traffic light which is on frame 16.

As far as I know, you can't get information about these keyframes in run-time. You can only do it with editor-code. If you really have to know which keyframe you are, you have to add events like this:

• Thank you for your message. I think keyframes are not the problem here. Would you take a look at my question again? I don't know how to explain it any other way than I already did. In my understanding, the calculation is pretty solid, so the number of frames played in LateUpdate should be just the same as the number of frames in the animation (51). Apr 11, 2021 at 12:01