Search Unity

Question Buildable way to get certain infos in AnimatorState and AnimatorController?

Discussion in 'Animation' started by Reekin, Dec 14, 2020.

  1. Reekin

    Reekin

    Joined:
    Oct 7, 2015
    Posts:
    10
    I have such codes that made me unable to build because of using UnityEditor namespace(Motion ,AnimatorState and AnimatorController)
    But I must get the length and speed of a not-playing clip in the statemachine by name to do some calc, is there any other way that doesn't use UnityEditor namespace to help me get these info?

    And, why can such important fields be placed in UnityEditor namespace? I feel really really confused.

    #Update:
    Most other infos have been found available through GetCurrentAnimatorStateInfo() and runtimeAnimatorController.animationClips.
    But, the speed of the state got from GetCurrentAnimatorStateInfo() is diffirent from what I set in Editor. I set the speed to 2 in statemachine, and it plays at 2x speed, but the value I get from GetCurrentAnimatorStateInfo() is 1. In which way can I get the "2" ?

    Code (CSharp):
    1.  
    2. ...
    3. layerName = "Basic";
    4. if (AniLength == 0)
    5. {
    6.     state = GetStateByName(actor.animator, AniClipName, layerName);
    7.     AniLength = (int) (((AnimationClip) (state.motion)).length / Time.fixedDeltaTime / state.speed);
    8. }
    9. ...
    10.  
    Code (CSharp):
    1.  
    2. public static AnimatorState GetStateByName(Animator animator, string stateName, string layerName = "Full")
    3. {
    4.     if (null == animator || string.IsNullOrEmpty(stateName) || null == animator.runtimeAnimatorController)
    5.         return null;
    6.     var layerID = GetLayerIDByName(animator, layerName);
    7.     var ac = animator.runtimeAnimatorController as AnimatorController;
    8.     var states = ac.layers[layerID].stateMachine.states;
    9.     if (null == states || states.Length <= 0) return null;
    10.     for (int tCounter = 0, tLen = states.Length; tCounter < tLen; tCounter++)
    11.     {
    12.         var state = states[tCounter].state;
    13.         if (state.name == stateName)
    14.             return state;
    15.     }
    16.  
    17.     return null;
    18. }
    19. public static int GetLayerIDByName(Animator animator, string layerName)
    20. {
    21.     AnimatorController ac = animator.runtimeAnimatorController as AnimatorController;
    22.     for (int i = 0; i < ac.layers.Length; i++)
    23.     {
    24.         if (ac.layers[i].name == layerName)
    25.         {
    26.             return i;
    27.         }
    28.     }
    29.  
    30.     return -1;
    31. }
    32.  
     
    Last edited: Dec 14, 2020
  2. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    2,570
    Those are things you simply can't do with Animator Controllers because that's how they designed them (i.e. stupidly). The best you could do is get the info you need in the editor and serialize it in a separate script so you can access it at runtime.

    I recommend checking out Animancer (link in my signature) which lets you avoid Animator Controllers and control everything directly at runtime.
     
    Reekin likes this.
  3. Reekin

    Reekin

    Joined:
    Oct 7, 2015
    Posts:
    10
    Thank you!