Search Unity

Current animator state name?

Discussion in 'Animation' started by Rodolfo-Rubens, Jun 9, 2015.

  1. Alic

    Alic

    Joined:
    Aug 6, 2013
    Posts:
    137
    Works great!
     
  2. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    erm... you can't use UnityEditor on builds though?
     
    kloot and atomicjoe like this.
  3. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Ah but that's awesome anyway and it gave me an idea!

    Here's what I did:
    Code (csharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. [RequireComponent(typeof(Animator))]
    5. public class AnimatorStatesInfoHelper : MonoBehaviour
    6. {
    7.     public Animator Animator;
    8.     public List<StateInfo> AnimatorStates;
    9.  
    10. #if UNITY_EDITOR
    11.     // Keep this out of the build
    12.     [ContextMenu("Validate States")]
    13.     private void OnValidate()
    14.     {
    15.         if (Animator == null)
    16.         {
    17.             Animator = GetComponent<Animator>();
    18.             if(Animator == null)
    19.             {
    20.                 return;
    21.             }
    22.         }
    23.  
    24.         var animator = Animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
    25.         AnimatorStates = new List<StateInfo>();
    26.  
    27.         foreach (var layer in animator.layers)
    28.         {
    29.             foreach (var state in layer.stateMachine.states)
    30.             {
    31.                 AnimatorStates.Add(new StateInfo()
    32.                 {
    33.                     Name = state.state.name,
    34.                     StateHash = state.state.nameHash
    35.                 });
    36.             }
    37.         }
    38.     }
    39. #endif
    40.  
    41.     public StateInfo GetCurrentAnimatorState(int layer)
    42.     {
    43.         if (Animator == null)
    44.         {
    45.             return null;
    46.         }
    47.  
    48.         var stateInfo = Animator.GetCurrentAnimatorStateInfo(layer);
    49.  
    50.         foreach (var state in AnimatorStates)
    51.         {
    52.             if (stateInfo.IsName(state.Name))
    53.             {
    54.                 return state;
    55.             }
    56.         }
    57.  
    58.         return null;
    59.     }
    60. }
    61.  
    62. public static class AnimatorExtension
    63. {
    64.     private static Dictionary<Animator, AnimatorStatesInfoHelper> _animatorMap = new Dictionary<Animator, AnimatorStatesInfoHelper>();
    65.  
    66.     public static StateInfo GetCurrentAnimatorState(this Animator animator, int layer)
    67.     {
    68.         AnimatorStatesInfoHelper animatorStatesInfoHelper;
    69.         if (_animatorMap.TryGetValue(animator, out animatorStatesInfoHelper))
    70.         {
    71.             if (animatorStatesInfoHelper == null)
    72.             {
    73.                 MapAnimator();
    74.             }
    75.         }
    76.         else
    77.         {
    78.             MapAnimator();
    79.         }
    80.         if (!animatorStatesInfoHelper)
    81.         {
    82.             Debug.LogWarning("Animator doesn't have a 'AnimatorStatesInfoHelper' attached to it.", animator);
    83.             return null;
    84.         }
    85.         return animatorStatesInfoHelper.GetCurrentAnimatorState(layer);
    86.  
    87.         void MapAnimator()
    88.         {
    89.             animatorStatesInfoHelper = animator.GetComponent<AnimatorStatesInfoHelper>();
    90.             if (animatorStatesInfoHelper != null)
    91.             {
    92.                 _animatorMap[animator] = animatorStatesInfoHelper;
    93.             }
    94.         }
    95.     }
    96. }
    97.  
    98. [System.Serializable]
    99. public class StateInfo
    100. {
    101.     public int StateHash;
    102.     public string Name;
    103. }
    104.  
    Attach this to an object that has an Animator and use the extension method GetCurrentAnimatorState (on Animator itself as I created an extension method to map this component to the animator automatically to avoid using GetComponent all the time and call the method on the correct component).

    The StateInfo returned by it will contain the name and the hash so you can use the way you want it. I'm suspect that the performance of this is not good (I didn't run any test though) as it does those comparisons and iterations every time.

    edit: oh, don't forget to run the "Validate States" through the component's context menu when making changes to its animator controller.
     
    Last edited: Aug 30, 2022
    Fangh likes this.
  4. Fangh

    Fangh

    Joined:
    Apr 19, 2013
    Posts:
    274
    This is the name of the clip. Not the name of the state in which the clip is playing
     
  5. demented_hedgehog

    demented_hedgehog

    Joined:
    Nov 14, 2014
    Posts:
    8
    It's terrible that this has not been fixed.
     
    kloot likes this.
  6. kloot

    kloot

    Joined:
    Mar 14, 2018
    Posts:
    78
    Yes, it's mind-boggling to think that this hasn't been fixed over the years.
    Can you imagine how unlikely it would be that none of us here on this thread would have taken care of this by now had Unity been an open source project?
    This (and soooo many more) threads on this this forum just serves as ads for going with an engine like Godot. Year after year after year...
     
  7. spilat12

    spilat12

    Joined:
    Feb 10, 2015
    Posts:
    38
    C'mon, it's been only 8 years, can we make it to 10 ? Jokes aside, seems like the best option is to keep state names unchanged, if possible. Then each state will be named after its animation clip, which you can get using something like this:
    Code (CSharp):
    1. animator.GetCurrentAnimatorClipInfo(layerIndex)[0].clip.name
     
    MagyarPeter likes this.
  8. mranderson744

    mranderson744

    Joined:
    Feb 16, 2023
    Posts:
    7
    2023 Unity: get animation state name is NOT POSSIBLE.

    trying hard to sync two animation controllers, still it is a BIG issue to make that work (it's 2023 just fyi)

    stupid code i'm forced to use because it's to hard to implement method to get a state name

    if(playerAnimator.GetCurrentAnimatorStateInfo(layerIndex).IsName("1")) {
    stateToPlay = "1";
    }
    if(playerAnimator.GetCurrentAnimatorStateInfo(layerIndex).IsName("2")) {
    stateToPlay = "2";
    }
     
    Last edited: Oct 6, 2023
    Sarai likes this.
  9. AAAAAAAAAE

    AAAAAAAAAE

    Joined:
    Jun 8, 2013
    Posts:
    100
    // Add an Animation Event to a GameObject that has an Animator
    using UnityEngine;
    using System.Collections;

    public class Example : MonoBehaviour
    {
    void Start()
    {
    animator = GetComponent<Animator>();


    foreach(AnimationClip clip in animator.runtimeAnimatorController.animationClips)
    {

    // new event created
    AnimationEvent evt = new AnimationEvent();

    evt.stringParameter= clip.name;
    //Transition time between animations must considered for actual
    // timing of event to fire

    evt.time = 0f;// if no transition offset
    //this will not work for forward_jump as entry is 0.26s
    //check image below
    evt.functionName = "TrackAnimClipEvent";


    clip.AddEvent(evt);
    }​
    }


    public void TrackAnimClipEvent(string s)
    {
    Debug.Log("PlayingClip: " + s);​
    }​
    }
    Screenshot 2023-11-23 152215.png

     
    Last edited: Nov 23, 2023
  10. MarkMaa

    MarkMaa

    Joined:
    Jan 20, 2020
    Posts:
    36
    no alternative unfortuanely.. I would definetely run away to it if there was one. I tried some other engines but none of them satisfied me so I'm stuck with unity :(
     
  11. LeakedDave

    LeakedDave

    Joined:
    Aug 26, 2012
    Posts:
    27
    Bump! Because, wtf? Why can't I get current state name? Hellooooo Unity team