Search Unity

Question Creating an Animator with AnimationClips when importing an FBX with animations

Discussion in 'Scripting' started by rafael_unity386, Jun 27, 2022.

  1. rafael_unity386

    rafael_unity386

    Joined:
    Jun 15, 2022
    Posts:
    14
    Hey everyone. So I'm making a script that does some things when importing a model that has animations. One of those things I want to do is creating an Animator with the animations already in it. I managed to create the animator but I can't find anything on adding the animations to it.
    I tried with
    Code (CSharp):
    1. ModelImporter modelImporter = assetImporter as ModelImporter;
    2.  
    3. controller = AnimatorController.CreateAnimatorControllerAtPath("Assets/Char_AnimControllers/" + modelName.Split('.')[0] + ".controller") // Creating the animator with the same name as my model but I'm taking only the part before the .fbx
    4. controller.AddMotion(modelImporter.clipAnimations[0]); //trying to add the first animation in the model
    But I get the error "cannot covert from 'UnityEditor.ModelImporterClipAnimation' to 'UnityEngine.Motion'".
    I'm trying this in the OnPostprocessModel function of the AssetPostProcessor

    How can I convert the Model Importer clips to Motion? Or how could I achieve what I'm trying to do?
     
    Last edited: Jun 27, 2022
  2. rafael_unity386

    rafael_unity386

    Joined:
    Jun 15, 2022
    Posts:
    14
    I tried using the AddMotion function in the OnPostprocessAnimation function instead, which has a reference to the AnimationClip.
    Code (CSharp):
    1. void OnPostprocessAnimation(GameObject go, AnimationClip clip)
    2.     {
    3.         controller.AddMotion(clip);
    4.     }
    This creates a state for each of the animation clips in the model, but the Motion field remains empty.


    Why is this happening? Is it just not possible to automatically create an animator with the animation clips from a model?
     
  3. rafael_unity386

    rafael_unity386

    Joined:
    Jun 15, 2022
    Posts:
    14
    I finally got it to work by doing this. Instead of trying to add each clip in the OnPostprocessAnimation function, I created this separate script:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. using UnityEditor.Animations;
    6. using Unity.EditorCoroutines.Editor;
    7.  
    8. public class AddAnimationClips : MonoBehaviour
    9. {
    10.     public static void AddClips(AnimatorController controller, string path, object owner)
    11.     {
    12.         EditorCoroutineUtility.StartCoroutine(AddingClips(controller, path), owner);
    13.     }
    14.     static IEnumerator AddingClips(AnimatorController controller, string path)
    15.     {
    16.         Debug.Log("Adding clips to animator");
    17.         yield return new EditorWaitForSeconds(1f);
    18.         var rootStateMachine = controller.layers[0].stateMachine; // todo Animator
    19.  
    20.         Object[] data = AssetDatabase.LoadAllAssetRepresentationsAtPath(path);
    21.         foreach (Object o in data)
    22.         {
    23.             if (o is AnimationClip)
    24.             {
    25.                 bool stateExists = false;
    26.                 for (int i = 0; i < rootStateMachine.states.Length; i++)
    27.                 {
    28.                     if (rootStateMachine.states[i].state.name == o.name)
    29.                     {
    30.                         stateExists = true;
    31.                     }
    32.                 }
    33.  
    34.                 if (!stateExists)
    35.                 {
    36.                     controller.AddMotion(o as AnimationClip);
    37.                 }
    38.             }
    39.         }
    40.         Debug.Log("Animation clips have been added");
    41.     }
    42. }



    Then at the end of my other script in the OnPostprocessModel function, I called the new script with this:

    Code (CSharp):
    1. AddAnimationClips.AddClips(controller, assetPath, this);