Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to get animation's current frame?

Discussion in 'Scripting' started by ScaryRobotGames, Jul 31, 2011.

Thread Status:
Not open for further replies.
  1. ScaryRobotGames

    ScaryRobotGames

    Joined:
    May 2, 2007
    Posts:
    57
    How can I find what current frame an animation in progress is at?

    For example, shiva3d has this command: animation.getPlaybackCursor ( object, layer ) which returns what the current frame of the animation in progress is at.

    I've dug through the docs and forum and haven't been able to find anything.

    Suggestions?
     
  2. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    Sorry, but Unity3d currently does not have this function.

    You can request it from the Wish List side of the forums if you want, and hopefully someone important will see it.

    But there may be other solutions such as animation blending with animation.CrossFade (animationName, crossFadeTime); for example if that's what you need.

    Or else the animation.isPlaying variable?
     
  3. Sycle

    Sycle

    Joined:
    Nov 24, 2009
    Posts:
    446
    Yes it does, although you have to check the animation's time value.

    Then to convert from time to frame you multiply by your animation's framerate. Just note that because of variable framerates, you're not guaranteed to be exactly on a frame so use greater than / less than to check if you've passed a given frame or are between the two frames you're looking for.

    eg:
    Code (csharp):
    1. //if animation is between frames 10 and 15
    2. if (animation["attack"].time > 0.333  < animation["attack"].time < 0.5) {
    3.     //do something interesting
    4. }
    Hope that helps!
     
    AutisticAristocrat, Zelek and jococo like this.
  4. ScaryRobotGames

    ScaryRobotGames

    Joined:
    May 2, 2007
    Posts:
    57
    @SomeGuy22 - thanks for the suggestions.

    @Sycle,

    Thanks! That's perfect. I used to use a range in shiva3D because I couldn't count on a frame not getting dropped and the code being skipped. So a range is just fine with me.

    I thought ".time" just returned the length of the anim. Glad to see that I was wrong.

    Thanks for the quick help.
     
  5. SomeGuy22

    SomeGuy22

    Joined:
    Jun 3, 2011
    Posts:
    722
    Whoops! Turns out I was wrong!

    Sorry for the confusion - I didn't even know of that method.
     
    Yoreki likes this.
  6. earthcrosser

    earthcrosser

    Joined:
    Oct 13, 2010
    Posts:
    122
    I used this to fix some animations that weren't looping correctly after upgrading to Unity 4
    in the Start function I have this:
    Code (csharp):
    1. Andy.animation.AddClip(Andy.animation.clip, "walk", 0, 29, true);
    I used to be able to just play the animation with the wrap mode set to LOOP but with Unity4 the animation would pause a few seconds before starting again. I noticed that if I stopped the animation it would play from the beginning again..so I just added this code in the update function... when it gets to frame 30 (then end of the walk animation above) it just stops. The result is the animation loops the way it should again. I do find it annoying to add this code in though.

    Code (csharp):
    1. if (Andy.animation["walk"].time*Andy.animation["walk"].clip.frameRate >=30){
    2.             Andy.animation.Stop("walk");
    3.         }
     
    jococo likes this.
  7. MdV303

    MdV303

    Joined:
    Jul 26, 2023
    Posts:
    1
    My solution to get the current frame of an animation (starting at 1), after calculating the number of frames in the animation:

    Code (CSharp):
    1. Animator _animator;
    2. float _numberOfFrames;
    3.  
    4. void Start()
    5. {
    6.     _animator = gameObject.GetComponent<Animator>();
    7.     AnimationClip clip = _animator.runtimeAnimatorController.animationClips[0];
    8.     _numberOfFrames = clip.length * clip.frameRate;
    9. }
    10.  
    11. void Update()
    12. {
    13.     float normalizedTime = _animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
    14.     int currentFrame = (int)(normalizedTime / (1 / _numberOfFrames)) + 1;
    15. }
    Use Mathf.Floor() to get the whole frame number if you don't want currentFrame to be declared as an int.

    (edit: apologies for replying to such an old topic...)
     
    Last edited: Aug 6, 2023
  8. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,036
    Thank you for your effort, but please don't reply to such old threads. The post is a dozen years old, the Unity has changed significantly since the question was asked. Closed.
     
Thread Status:
Not open for further replies.