Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

How can i get a List<string> of all animations clips in Animation.animations ?

Discussion in 'Scripting' started by Chocolade, May 8, 2017.

  1. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    916
    I have added to a Camera a Animation component and changed the Animations size to 2. Added two clips.
    Then in the script in the top:

    Code (csharp):
    1.  
    2. Animation _animation;
    3. List<string> animations = new List<string>();
    4.  
    In Start

    Code (csharp):
    1.  
    2. private void Start()
    3.     {
    4.         _animation = GetComponent<Animation>();
    5.  
    6.         foreach (AnimationState state in _animation)
    7.         {
    8.            
    9.             animations.Add(state.name);
    10.         }
    11.         int n = _animation.GetClipCount();
    12.     }
    13.  
    But for some reason animations is empty count 0. But the variable n value is 2.
    What i want to get all the Animations in the array.

    I'm using unity 5.5.1f1 personal
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    The Animation component is a legacy component - you should only use it if you're really sure you know what you're doing, or are maintaining code that was written before its replacement existed.

    Its replacement is Animator, and this information is available in that class via .runtimeAnimationController.animationClips

    That said, I think the code you're using should work as written - but if it's a Unity bug, I doubt it'll get fixed at this point.
     
  3. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    916
    Thanks found another way to do what i need without the Animation component at all. Sorry for the mess.
     
  4. N0NameDev

    N0NameDev

    Joined:
    Nov 14, 2021
    Posts:
    2
    HOW????????????????????????????????????????????????????????????????????????
     
    theCodeHermit likes this.
  5. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,741
    Start a new thread with your own situation and your own thread. It's unlikely that this person's exact workaround will be exactly like what you need for your situation, and more unlikely that they'll come back and answer you 5 years after their post.
     
  6. DeveloperJake

    DeveloperJake

    Joined:
    May 25, 2020
    Posts:
    13
    You've gotta tell us what the solution was when you get the solution please.
     
  7. Antonius007

    Antonius007

    Joined:
    Aug 26, 2020
    Posts:
    5
    I can confirm it works with Unity 2021.2.8f1
     
  8. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,043
    I can't find how to make the List or an Array visible in the inspector. and this is one of those things about Unity that is beyond infuriating...

    But here's how to get that array of names:

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. public class AnimControlLetter : MonoBehaviour {
    5.  
    6.     [SerializeField] private Animation _anim;
    7.     [SerializeField] private AnimationClip[] _clips;
    8.     [SerializeField] private int _clipCount;
    9.     [SerializeField] private int clipToRun;
    10.     public string[] _clipNames;
    11.  
    12.     void Start ( ) {
    13.         if ( _anim == null ) _anim = GetComponent<Animation>(  );
    14.         _clipCount = _anim.GetClipCount( );
    15.         _clips = new AnimationClip[_clipCount];
    16.         _clips = AnimationUtility.GetAnimationClips( this.gameObject );
    17.         _clipNames = new string[_clipCount];
    18.         for ( int i = 0; i < _clips.Length; i++ ) {
    19.             _clipNames[i] = _clips[i].name;
    20.         }
    21.     }
    22. }
    23.  
     
    madfish-od likes this.
  9. nukadelic

    nukadelic

    Joined:
    Aug 5, 2017
    Posts:
    65
    upload_2023-6-14_2-46-30.png

    here is a little script the will auto fetch all the clip names and add a button that will play the animation in play mode :

    Code (CSharp):
    1. using System.Linq;
    2. using UnityEngine;
    3. #if UNITY_EDITOR
    4. using UnityEditor;
    5. #endif
    6.  
    7. public class AnimPlayer : MonoBehaviour
    8. {
    9.     public Animator animator;
    10.  
    11.     string currentState = "none";
    12.  
    13.     [HideInInspector] public string[] clips;
    14.  
    15.     private void OnValidate()
    16.     {
    17.         if( animator != null )
    18.         {
    19.             clips = animator
    20.                 .runtimeAnimatorController
    21.                 .animationClips
    22.                 .Select( x => x.name )
    23.                 .ToArray();
    24.         }
    25.     }
    26.  
    27.     private void Awake()
    28.     {
    29.         currentState = animator.GetCurrentAnimatorClipInfo( 0 )[ 0 ].clip.name;
    30.     }
    31.  
    32.     public void Play( string newState )
    33.     {
    34.         if( ! Application.isPlaying ) return;
    35.  
    36.         if( currentState == newState ) return;
    37.  
    38.         animator.Play( newState );
    39.  
    40.         currentState = newState;
    41.     }
    42.  
    43.     #if UNITY_EDITOR
    44.  
    45.     [CustomEditor(typeof(AnimPlayer))]
    46.     class Inspector : Editor
    47.     {
    48.         int nextClip = 0;
    49.  
    50.         int[] intvalues;
    51.  
    52.         public override void OnInspectorGUI()
    53.         {
    54.             base.OnInspectorGUI();
    55.  
    56.             GUILayout.Space( 7 );
    57.  
    58.             var script = ( AnimPlayer ) target;
    59.  
    60.             intvalues = new int[ script.clips.Length ];
    61.  
    62.             for( var i = 0; i < intvalues.Length; ++ i ) intvalues[ i ] = i ;
    63.  
    64.             using ( new GUILayout.HorizontalScope() )
    65.             {
    66.                 nextClip = EditorGUILayout.IntPopup( nextClip, script.clips, intvalues );
    67.  
    68.                 if( GUILayout.Button("Play") )
    69.                 {
    70.                     script.Play( script.clips[ nextClip ] );
    71.                 }
    72.             }
    73.  
    74.         }
    75.     }
    76.  
    77.     #endif
    78. }
     
    Unifikation likes this.
  10. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,379
    @VVad, you should note that this thread is a bit on the old side. And with that, it is also referencing the older legacy 'Animation' class not the contemporary 'Animator' class.
     
  11. nukadelic

    nukadelic

    Joined:
    Aug 5, 2017
    Posts:
    65
    Yes i am aware , and here is one for the Animator class ( also works in edit mode ) , this one is a standalone animation clip player without the need to create animation controller asset , works with 2d sprites and 3d skinned mesh renderers

    upload_2023-6-15_10-5-28.png

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine;
    3. using UnityEngine.Animations;
    4. using UnityEngine.Playables;
    5. using UnityEngine.SceneManagement;
    6.  
    7. [ExecuteAlways] public class PlayClip : MonoBehaviour
    8. {
    9.     // -------------------------------------------------------
    10.  
    11.     public void Pause() { this.enabled = false; }
    12.  
    13.     public void Play() { this.enabled = true; }
    14.  
    15.     public void LastFrame()
    16.     {
    17.         playable.GetAnimationClip().SampleAnimation(gameObject, duration);
    18.  
    19.         graph.Stop();
    20.     }
    21.  
    22.     public event System.Action<PlayClip> OnClipLoop;
    23.  
    24.     public AnimationClip GetClip()
    25.     {
    26.         return m_Clip;
    27.     }
    28.  
    29.     public void SetSpeed(float speed)
    30.     {
    31.         m_Speed = speed;
    32.  
    33.         Validate();
    34.        
    35.         // if( playable.IsValid() ) playable.SetSpeed( m_Speed );
    36.     }
    37.  
    38.     public void SetClip( AnimationClip clip )
    39.     {
    40.         m_Clip = clip;
    41.  
    42.         Validate();
    43.     }
    44.  
    45.     public void SetClip( AnimationClip clip , float speed )
    46.     {
    47.         m_Speed = speed;
    48.         m_Clip = clip;
    49.  
    50.         Validate();
    51.  
    52.         // if( playable.IsValid() ) playable.SetSpeed( m_Speed );
    53.     }
    54.  
    55.     public void SetClip( AnimationClip clip , System.Action callback )
    56.     {
    57.         SetClip( clip , m_Speed , callback );
    58.     }
    59.  
    60.     public void SetClip( AnimationClip clip, float speed , System.Action callback )
    61.     {
    62.         m_LastClip = clip;
    63.         m_LastClipCapture = true;
    64.         m_LastClipCallback = callback;
    65.  
    66.         SetClip( clip , speed );
    67.     }
    68.  
    69.     public void SetClip( AnimationClip clip , AnimationClip next_clip )
    70.     {
    71.         SetClip( clip, m_Speed, next_clip, m_Speed );
    72.     }
    73.  
    74.     public void SetClip( AnimationClip clip , float speed , AnimationClip next_clip , float next_speed )
    75.     {
    76.         SetClip( clip, speed, () => SetClip( next_clip, next_speed ) );
    77.     }
    78.  
    79.     // -------------------------------------------------------
    80.    
    81.     public bool isPlaying { private set; get; } = false;
    82.     public bool isPaused { private set; get; } = false;
    83.     public float duration { private set; get; } = 0f;
    84.     public int loopCount { private set; get; } = 0;
    85.     public float clipProgress { private set; get; } = 0; // 0 to 1
    86.  
    87.     // -------------------------------------------------------
    88.  
    89.     [SerializeField]        AnimationClip m_Clip;
    90.  
    91.     [SerializeField]
    92.     [Range(0f,3.5f)]        float m_Speed = 1f;
    93.  
    94.     [Space(10)]
    95.    
    96.     public UnityEngine.Events.UnityEvent<PlayClip> EventClipLoop;
    97.  
    98.     // -------------------------------------------------------
    99.  
    100.     [System.NonSerialized]  AnimationClip prev;
    101.     [System.NonSerialized]  Animator animator;
    102.     [System.NonSerialized]  PlayableGraph graph;
    103.     [System.NonSerialized]  AnimationClipPlayable playable;
    104.  
    105.     // -------------------------------------------------------
    106.    
    107.     // bool hasPlayable => ! playable.Equals( default( AnimationClipPlayable ) );
    108.  
    109.     // -------------------------------------------------------
    110.  
    111.     AnimationClip m_LastClip;
    112.     System.Action m_LastClipCallback;
    113.     bool m_LastClipCapture = false;
    114.  
    115.     void LastClipCapture()
    116.     {
    117.         if ( ! m_LastClipCapture ) return;
    118.        
    119.         m_LastClipCapture = false;
    120.  
    121.         if ( m_LastClip != m_Clip ) return;
    122.        
    123.         m_LastClipCallback.Invoke();
    124.     }
    125.  
    126.     // -------------------------------------------------------
    127.  
    128.     private void Update()
    129.     {
    130.         if( ! isPlaying || isPaused ) return;
    131.  
    132.         var anim_time = (float) ( playable.GetTime() / duration );
    133.  
    134.         clipProgress = anim_time % 1;
    135.  
    136.         if ( graph.IsPlaying() && anim_time >= ( 1 + loopCount ) )
    137.         {
    138.             loopCount ++ ;
    139.  
    140.             if( Application.isPlaying )
    141.             {
    142.                 OnClipLoop?.Invoke( this );
    143.  
    144.                 LastClipCapture();
    145.             }
    146.         }
    147.     }
    148.  
    149.     void OnEnable()
    150.     {
    151.         #if UNITY_EDITOR
    152.         if( ! Application.isPlaying )
    153.             UnityEditor.SceneManagement.EditorSceneManager.sceneSaved += OnSaved;
    154.         #endif
    155.        
    156.         AttachAnimator();
    157.  
    158.         Validate();
    159.  
    160.         if( m_Clip != null )
    161.         {
    162.             if( isPaused && isPlaying )
    163.             {
    164.                 isPaused = false;
    165.  
    166.                 playable.Play();
    167.  
    168.                 return;
    169.             }
    170.  
    171.             ForcePlay();
    172.         }
    173.     }
    174.  
    175.     void OnSaved(Scene scene)
    176.     {
    177.         if ( enabled ) ForcePlay();
    178.     }
    179.  
    180.     public void ForcePlay()
    181.     {
    182.         if( m_Clip == null || animator == null ) return;
    183.  
    184.         Clean();
    185.  
    186.         playable = AnimationPlayableUtilities.PlayClip(animator, m_Clip, out graph);
    187.         playable.SetSpeed( m_Speed );
    188.         playable.Play();
    189.  
    190.         loopCount = 0;
    191.         duration = m_Clip.averageDuration / m_Speed;
    192.  
    193.         isPlaying = true;
    194.  
    195.         prev = m_Clip;
    196.     }
    197.  
    198.     void AttachAnimator()
    199.     {
    200.         if ( animator == null && ! gameObject.TryGetComponent( out animator ) )
    201.             animator = gameObject.AddComponent<Animator>();
    202.  
    203.         animator.runtimeAnimatorController = null;
    204.  
    205.         animator.hideFlags = HideFlags.HideInInspector;
    206.     }
    207.  
    208.     // public bool debug = false;
    209.  
    210.     void OnValidate()
    211.     {
    212.         if( isActiveAndEnabled )
    213.         {
    214.             AttachAnimator();
    215.             Validate();
    216.         }
    217.  
    218.         // animator.hideFlags = debug ? HideFlags.None : HideFlags.HideInInspector;
    219.     }
    220.  
    221.     void Validate()
    222.     {
    223.         if ( m_Clip == null ) prev = null;
    224.  
    225.         if (m_Clip != null && m_Clip != prev )
    226.         {
    227.             ForcePlay();
    228.  
    229.             return;
    230.         }
    231.  
    232.         if ( isPlaying && playable.IsValid() )
    233.            
    234.             playable.SetSpeed( m_Speed );
    235.  
    236.         else ForcePlay();
    237.     }
    238.  
    239.     private void OnDisable()
    240.     {
    241.         #if UNITY_EDITOR
    242.         if( ! Application.isPlaying )
    243.             UnityEditor.SceneManagement.EditorSceneManager.sceneSaved -= OnSaved;
    244.         #endif
    245.  
    246.         if( isPlaying && playable.IsValid() )
    247.         {
    248.             isPaused = true;
    249.  
    250.             playable.Pause();
    251.         }
    252.     }
    253.  
    254.     void OnDestroy()
    255.     {
    256.         Clean();
    257.  
    258.         if ( animator )
    259.         {
    260.             if ( Application.isPlaying ) Destroy( animator );
    261.            
    262.             else animator.hideFlags = HideFlags.None;
    263.         }
    264.     }
    265.  
    266.     void Clean()
    267.     {
    268.         if ( playable.IsValid() ) playable.Destroy();
    269.  
    270.         if ( graph.IsValid() ) graph.Destroy();
    271.  
    272.         isPlaying = false;
    273.     }
    274. }