Search Unity

Getting or calculating the average velocity of animations

Discussion in 'Animation' started by RamzaB, Jan 26, 2015.

  1. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    I'd like to create a script to get/calculate the average velocity of animations in the editor (not runtime).
    The value should be the same as what is displayed in the animation importer settings, but I'd like to calculate/get it using scripts instead of looking at my animations one by one.

    Is there any way to do this ? I've been trying a lot of stuffs, but for some reason, I can't seem to find the way to get the animation data in the Editor.
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    The bass class of an AnimationClip is called Motion and there is some hidden property that will give you this information

    Motion.averageDuration
    Motion.averageAngularSpeed
    Motion.averageSpeed
    Motion.apparentSpeed
     
    ph3rin likes this.
  3. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    Thanks you !.
    I did some tests, and found out that by using Animator.GetCurrentAnimationClipState, I could access the AnimationClip, and thus the above variables that you mentioned.

    However, this approach requires the animator to be active first. Is there any way to get access to the data directly without using Animator ?
     
  4. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Yes if you know clips used by the controller.

    In 5.0 we did add a new property on the AnimatorController
    AnimatorController.animationClips

    In 4.x it more complicated, you need to use some Editor class from the internal namespace UnityEditorInternal
    Code (CSharp):
    1.  
    2. class AnimatorController
    3. {
    4.   int                                     layerCount;
    5.   AnimatorControllerLayer GetLayer(int index);
    6. }
    7.  
    8. class AnimatorControllerLayer
    9. {
    10.   StateMachine stateMachine
    11. }
    12.  
    13. class State
    14. {
    15.   Motion State.GetMotion()
    16. }
    17.  
    18. class StateMachine
    19. {
    20.   int                    StateMachine.stateCount;
    21.   State               StateMachine.GetState(int index);
    22.   int                    StateMachine.stateMachineCount
    23.   StateMachine  StateMachine.GetStateMachine(int index)
    24. }
    25.  
    So basicaly
    you start from the controller
    get the controller's layer
    get layer's statemachine
    get statemachine's state
    State Machine can contain a statemachine too so you need to go down recursively to collect all the state
     
  5. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    Thank you. I will try this soon and let you know how it goes.
     
  6. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    I am using Unity 4.6, and I can confirm that this works ! Thank you !
    There was one issue that I had to do solve though, and that is to find out how to gain access to AnimatorController, but thanks to this Japanese site, I found out how to solve it.

    The code:
    Code (CSharp):
    1. Animator animator = selectedObject.GetComponent<Animator>();
    2. RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController;
    3.  
    4. UnityEditorInternal.AnimatorController ac = runtimeAnimatorController as UnityEditorInternal.AnimatorController;
    At the end of the day though, we still have to access it through Animator class. I guess that is the only way ?

    And, just to share my experiments, I found that these variables don't exist when building the app.

    Motion.averageDuration
    Motion.averageAngularSpeed
    Motion.averageSpeed
    Motion.apparentSpeed

    So, if I want to use them, I have to take them out first using the Editor and store them somewhere.
    Is this how it is designed ? Or will these variables be available during runtime on later versions of Unity ?
     
  7. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    Yes it the best way to access it at runtime

    Yes if you look as the first post from this thread it was for editor code only. We could probably expose those member at runtime eventually.
     
  8. kuziki

    kuziki

    Joined:
    Aug 12, 2016
    Posts:
    1
    When the AnimationType is "Humanoid", we can get average velocity from
    Motion.averageSpeed
    Motion.apparentSpeed

    But problem is: If AnimationType is "Generic", these two APIs will return 0.
    So how can we get average velocity when the AnimationType is "Generic"? (like dragon, horse or any other non-human like skeleton)
     
  9. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    look like a bug, it should work.

    Please log a bug and we will investigate.
     
  10. kkrzychu

    kkrzychu

    Joined:
    Dec 8, 2012
    Posts:
    1
    It looks like these properties are too small (e.g. it shows 3.6 but real speed is 10). How are they calculated?
     
  11. pixlhero

    pixlhero

    Joined:
    Jan 30, 2017
    Posts:
    1
    I would like to know that too. I HAVE to know the velocity of the animation and those values aren't correct.