Search Unity

Getting AnimationClip from FBX in the Editor (Mecanim)

Discussion in 'Animation' started by RamzaB, Feb 2, 2015.

  1. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    Hi,

    I am trying to do some post processing on my animation clips whenever they are imported, so I figured out that using AssetPostProcesssor is the right way to do it.

    However, the gameobject that is passed to OnPostprocessModel doesn't seem to have this information.

    As a workaround, I thought that I might get this information from the Animator's RuntimeAnimationController, but it's still set to null in OnPostprocessModel(), which actually makes sense after pondering a little bit, because it's just an animation clip and there shouldn't be any AnimationController set at this time.

    So, I am wondering, is there anyway to get those animation clips in the Editor ?
     
  2. Mecanim-Dev

    Mecanim-Dev

    Joined:
    Nov 26, 2012
    Posts:
    1,675
    What would you like to do exactly?

    You can either change the modelimporter setting for your clip or modify directly the read-only clip.
    Code (CSharp):
    1.  
    2. public void OnPostprocessModel(GameObject root)
    3.     {
    4.         // Modify ModelImporter meta data and reimport the asset
    5.         ModelImporter modelImporter = assetImporter as ModelImporter;
    6.  
    7.         ModelImporterClipAnimation[] clipAnimations = modelImporter.clipAnimations;
    8.         foreach (ModelImporterClipAnimation clip in clipAnimations)
    9.         {
    10.             clip.loopTime = true;
    11.         }
    12.         modelImporter.clipAnimations = clipAnimations;
    13.         AssetDatabase.ImportAsset(assetPath);
    14.  
    15.         // or get animation Clip
    16.         Object[] objects = AssetDatabase.LoadAllAssetsAtPath(assetPath);
    17.         foreach (Object obj in objects)
    18.         {
    19.             AnimationClip clip = obj as AnimationClip;
    20.             if (clip != null)
    21.             {
    22.                 .....
    23.             }
    24.         }
    25.     }
    26.  
     
    unpackable_orange and ModLunar like this.
  3. RamzaB

    RamzaB

    Joined:
    Nov 4, 2012
    Posts:
    42
    I didn't know that LoadAllAssetsAtPath (nor LoadAllAssetsRepresentationsAtPath) function existed. Thank you ! It works.

    I wanted to store the hidden properties of the AnimationClips in my own custom data format, like averageSpeed, etc.
    Like what you said in this thread:
    http://forum.unity3d.com/threads/ge...e-velocity-of-animations.293507/#post-1941896

    Those variables do not seem to be exposed in the runtime right now, and since I need them during run time, I figured out that I should store them somewhere
     
  4. BoBo-san

    BoBo-san

    Joined:
    Jan 29, 2011
    Posts:
    11
    I would like to modify imported animation's curve to minimize artist's manual work.

    From the document, when OnPostprocessModel is called, Nothing is saved on Disk yet.
    So the code above won't return imported animation clip.

    Is there anyway to get imported animation clip?

    -----------------------------------------------------------------------------------------------------

    EDIT : ok after pulling my hair a bit.

    I use the following code to get imported animation.
    This can also get a new split animation clip.
    AssetDatabase.LoadAllAssetsAtPath will only return animation curve before modify splitting animation clip.

    Code (CSharp):
    1.  
    2. public void OnPostprocessModel(GameObject root)
    3.     {
    4.             AnimationClip[] clips = AnimationUtility.GetAnimationClips(gameObject);
    5.  
    6.             if (clips.Length == 0)
    7.             {
    8.                 clips = Object.FindObjectsOfType<AnimationClip>();
    9.             }
    10.  
    11.             HashSet<string> importClipName = new HashSet<string>();
    12.             ModelImporter modelImporter = assetImporter as ModelImporter;
    13.  
    14.             for (int i = 0; i < modelImporter.clipAnimations.Length; ++i)
    15.             {
    16.                 importClipName.Add(modelImporter.clipAnimations[i].name);
    17.             }
    18.  
    19.             for (int i = 0; i < clips.Length; ++i)
    20.             {
    21.                 AnimationClip clip = clips[i];
    22.                 bool saveClip = false;
    23.                 if (clip != null &&
    24.                     importClipName.Contains(clip.name) &&
    25.                     !EditorUtility.IsPersistent(clip))
    26.                 {
    27.                     // YOUR CODE
    28.                 }
    29.             }
    30.     }
    31.  
    The imported animation clip here won't be saved on the disk.
    Even though you modify clip's curve here, It won't save because model's meta file only store setting form ModelImporterClipAnimation.

    So, Consider store your information in ModelImportedClipAnimation or save your clip as a separate file.

    FYI, If you use AssetDatabase.CreateAsset over existing clip, Unity will assign new GUID and you will lose reference.
     
    Last edited: Dec 29, 2016
    ModLunar likes this.
  5. unpackable_orange

    unpackable_orange

    Joined:
    Jun 14, 2023
    Posts:
    1
    This helps me a lot to get the AnimationClip. Thanks!
    I do this to get the AnimationClip in fbx file and add it to a AnimatorController.

    Code (CSharp):
    1. ModelImporter modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter;
    2. if(modelImporter == null){
    3.        Debug.Log("NULL");
    4. }
    5. modelImporter.clipAnimations = modelImporter.defaultClipAnimations;
    6. ModelImporterClipAnimation clip = modelImporter.clipAnimations[0];
    7. Object clipObj = AssetDatabase.LoadAssetAtPath(assetPath, typeof(AnimationClip));
    8. AnimationClip ani_clip = clipObj as AnimationClip;
    9. AnimatorStateMachine stateMachine = layer.stateMachine;
    10. AnimatorState newState = stateMachine.AddState(clip.name);
    11. newState.motion = ani_clip;