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 can I get all the animation clips imported from an FBX? SOLVED!

Discussion in 'Scripting' started by EnriqueGato, Sep 17, 2016.

  1. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    I have a character in my Assets folder and I'd like to access its animation clips to sort them and create new ones by code.

    I tryed to access them with AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) with no luck.

    Any ideas?

    Thanks
     
    Last edited: Sep 17, 2016
  2. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    when you imported the model into unity it should have imported the animations as well. it may have imported them all as a single clip or multiple clips. if it a single clip, then you'll have to tell unity how many clips it has and what frames to stop and start each animation
     
  3. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    Here, this should help:

    Code (CSharp):
    1.  
    2. using UnityEditor;
    3. //get the animations in the object
    4.     AnimationClip[] animations = AnimationUtility.GetAnimationClips(MyObject);
    Just bear in mind, if I remember well, that this code is for use in editor or within a clause #if Unity editor, so you'll have to save that in a public array or List or something to not lose the data when you enter playmode. I used a similar method to create an editor which allows the user to get a dropdown with all the animations in the object (no need for writing names :) ). You can take a look at the base code here.
     
    Last edited: Sep 17, 2016
    MarcSpraragen and radiantboy like this.
  4. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    Thanks a lot Alverik. I didn't know the existance of the AnimationUtility class.

    Anyway, maybe I'm doing something wrong, but I'm getting an empty array with this code.
    Code (CSharp):
    1. var _asset = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Models/chr/chr_fatman/chr_fatman.fbx");
    2. AnimationClip[] animations = AnimationUtility.GetAnimationClips(_asset);
    3.  
    And of course it's totally checked that the asset exists and it has animations.
     
  5. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    That looks off to me. You have to make a prefab of the character, so that Unity creates the Animator controller and Animator, etc. Without those, AFAIK, it wont work (the code is taking the list of animations from one of those components after all). Once you have the prefab, just pass it to the script instead of the .fbx...
     
  6. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    Ok. What I'm actually trying to access and modify is the base imported model and the multiple clips defined:
    animClips.jpg
     
  7. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    you need a 3d program to modify the 3d models and there bones to make changes to the animations.
    3ds max, Maya, or the free Blender
     
  8. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    Don't think you can actually modify those, they're probably read only anyway. You could try selecting them and duplicate them which would give you a copy of the data, but I'm not sure how you could access them directly. I've never done procedural animation in Unity, but usually, you'd just use physics forces or vector movement to animate objects through code. Not sure how that would go when making animation from scratch for skinned meshes though. I have seen some assets for posing and animating skinned models inside Unity, like Skele Character Animation tools, but never heard of them doing it procedurally at runtime based on other animations... Anyway, I'll try checking about it too, but I can't promise anything.

    ...By the way, you don't need to change the bones to change the animations... else all the animations they sell in the asset store would be useless....
     
  9. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    Thanks a million for the effort, but I think I'm not getting to show the whole picture and the final point of this. Let's see if this helps.

    The thing is I imported an FBX model with multiple animations in it. I defined the animation ranges in the Animations tab in the inspector, one by one, attending to the original ranges in the 3D software. That creates the animation clips.

    animClips2.jpg

    The thing is, now all those ranges changed on the 3D software, and I don't want to edit them one by one again in Unity. So I made a tool to export the ranges from the 3D software, and now I just need to import the ranges in Unity. That's why I need to access the clip ranges on the asset, not on the prefab.

    Thanks in advance
     
    skoteskote likes this.
  10. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    Thanks, for clarifying that, but, ummm... what modeling software are you using? That's seems a bit pointless to me... doesn't your 3D modeling software have an option to create "actions" or separate animation clips like in Blender? That automatically gives you separate animation clips on import without needing to define any ranges at all... but, anyway, I'll do a search and see if there's anything mentioned about this.
     
  11. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
  12. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    Yes! Yes, it worked!!!

    God, I was like 3 hours looking for threads like those you posted with no luck. I was using totally wrong keywords for the search. The first thread was more than enough to solve it.
    Code (CSharp):
    1.  
    2. ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(assetPath);
    3. ModelImporterClipAnimation clip = modelImporter.clipAnimations[0]; // get first clip
    4. Debug.Log(clip.startFrame);
    5. Debug.Log(clip.stopFrame);
    6.  
    As there's no reverence emoticon I'll just say thanks again. You saved me hours of desperation :)
     
  13. EnriqueGato

    EnriqueGato

    Joined:
    Sep 3, 2016
    Posts:
    81
    Unfortunately, my old 3dsMax doesn't have this feature of specifying the ranges of the clips, so it's impossible to transfer the information unless you have a custom tool.
     
    Alverik likes this.
  14. Alverik

    Alverik

    Joined:
    Apr 15, 2016
    Posts:
    417
    Alright, I'm just happy to hear you got it working :)
    Cheers!
     
  15. Devilwhale

    Devilwhale

    Joined:
    Jul 29, 2015
    Posts:
    4
    In editor I was not able to get Model Importer working. However simply found you can load any component from a game object this way.
    I grab the object, then use its path to grab other components off it. (getcomponent did not work for me either)
    Code (CSharp):
    1. srcanimator = EditorGUILayout.ObjectField(srcanimator, typeof(Animator), true) as Animator;
    2. AnimationClip a = (AnimationClip)AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(srcanimator.gameObject),typeof(AnimationClip));
     
  16. Dr-Nick

    Dr-Nick

    Joined:
    Sep 9, 2013
    Posts:
    25
    Great. This thread really helped me out.
     
  17. infinitedev

    infinitedev

    Joined:
    Oct 24, 2013
    Posts:
    3
    I figured out how to really do this. The AssetDatabase class also provides a
    LoadAllAssetRepresentationsAtPath method, which will return all objects contained by assets, such as AnimatioClip, Material, Mesh, etc..

    https://docs.unity3d.com/ScriptReference/AssetDatabase.LoadAllAssetRepresentationsAtPath.html

    So, the below works!

    Code (CSharp):
    1. var path = "Assets/foo.fbx";
    2.          
    3.             var assetRepresentationsAtPath = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
    4.          
    5.             foreach (var assetRepresentation in assetRepresentationsAtPath) {
    6.                 var animationClip = assetRepresentation as AnimationClip;
    7.  
    8.                 if (animationClip != null) {
    9.                     Debug.Log("Found animation clip");
    10.                 }
    11.             }
     
  18. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633

    Do you know how to convert a ModelImporterClipAnimation to an AnimationClip ?
     
  19. neoRiley

    neoRiley

    Joined:
    Dec 12, 2008
    Posts:
    158
    Did you ever get an answer on how to convert ModelImporterClipAnimation to an AnimationClip?
     
  20. kozorezovChillgaming

    kozorezovChillgaming

    Joined:
    Sep 3, 2019
    Posts:
    1
    Code (CSharp):
    1. var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(fbxFilePath);
    Another way to convert or cast, I have not found
     
    MarcSpraragen and radiantboy like this.
  21. zORg_alex

    zORg_alex

    Joined:
    Mar 12, 2014
    Posts:
    20
    Thanks. I was looking into how to rename Animation clips imported from FBXes from Mixamo. They all have "mixamo.com" instead of names. That is really annoying since you can't discern them one from another when listed.
    So I've made a single click tool editor window with this:

    Code (CSharp):
    1.     void FixNamingInAnimations() {
    2.         foreach (GameObject o in Selection.objects) {
    3.             ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(o));
    4.             var clips = modelImporter.clipAnimations;
    5.             foreach (var c in clips) {
    6.                 if (c.name == "mixamo.com") c.name = o.name;
    7.             }
    8.             modelImporter.clipAnimations = clips;
    9.         }
    10.     }
    Thank you all for this thread. This is what holds up the whole game dev on Unity.
     
  22. rhodnius

    rhodnius

    Joined:
    Apr 11, 2012
    Posts:
    1,334
    is really easier than it seems, if you just name the fbx like bot@run.fbx unity would import that animation as run taking the name from the fbx file ;)
     
  23. Akidamaru

    Akidamaru

    Joined:
    Sep 8, 2015
    Posts:
    7
    Hi, I dont know if it will be useful but you can get all the AnimationClips in a ModelImporter this way (the class doesnt have to be static):

    Code (CSharp):
    1. public static AnimationClip[] GetAnimationClipsFromImporter(string modelImporterPath)
    2.         {
    3.             var animationClips = new List<AnimationClip>();
    4.  
    5.             var modelImporterAssets = AssetDatabase.LoadAllAssetsAtPath(modelImporterPath);
    6.             foreach (var asset in modelImporterAssets)
    7.             {
    8.                 if (asset is AnimationClip clip)
    9.                 {
    10.                     animationClips.Add(clip);
    11.                 }
    12.             }
    13.  
    14.             return animationClips.ToArray();
    15.         }
     
    the_Whizzkid likes this.