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.

Question How do I create a curve during post animation import

Discussion in 'Animation' started by Nathanieljla, Sep 23, 2022.

  1. Nathanieljla

    Nathanieljla

    Joined:
    Apr 18, 2014
    Posts:
    97
    TLDR How do I create a curve during post animation import?
    upload_2022-9-23_9-55-5.png

    I'd like to extract root Motion data and store it into some editor created Animation clip curves. I figured it's best to do this during UnityEditor.AssetPostprocessor.OnPostprocessAnimation. However, both clip.SetCurve() and AnimationUtility.SetEditorCurve() need to know the EditorCurveBinding.Type, which I don't know and all the examples I've seen for creating curves use existing component properties. I tried doing TypeOf(AnimationCurve), but this does not inherit from Object, so the import failed. Maybe I'm going about this wrong. Any thoughts? Thanks!
     
  2. Nathanieljla

    Nathanieljla

    Joined:
    Apr 18, 2014
    Posts:
    97
    You can do something like:

    Code (CSharp):
    1.  
    2.     public class AnimRootMotionExtractor : UnityEditor.AssetPostprocessor {
    3.        void OnPostprocessAnimation(GameObject root, AnimationClip clip){
    4.            Keyframe[] keys;
    5.            keys = new Keyframe[3];
    6.            keys[0] = new Keyframe(0.0f, 0.0f);
    7.            keys[1] = new Keyframe(0.1f, 1.5f);
    8.            keys[2] = new Keyframe(.5f,  2f);
    9.            AnimationCurve curve = new AnimationCurve(keys);
    10.  
    11.            EditorCurveBinding binding = EditorCurveBinding.FloatCurve("", typeof(UnityEngine.Animator), "Joe");
    12.            AnimationUtility.SetEditorCurve(clip, binding, curve);
    13.        }
    14.    }
    15.  

    The curve "Joe" won't show up in the Import settings (since that's meta data, and you're not writing to the meta file), but the generated data will contain the curve.

    To help verify the data is there I used a modified version of the sample code found here that looks for the param

    Code (CSharp):
    1. public class ClipInfo : EditorWindow
    2. {
    3.     private AnimationClip clip;
    4.  
    5.     [MenuItem("Window/Clip Info")]
    6.     static void Init()
    7.     {
    8.         GetWindow(typeof(ClipInfo));
    9.     }
    10.  
    11.     public void OnGUI()
    12.     {
    13.         clip = EditorGUILayout.ObjectField("Clip", clip, typeof(AnimationClip), false) as AnimationClip;
    14.  
    15.         EditorGUILayout.LabelField("Curves:");
    16.         if (clip != null)
    17.         {
    18.             foreach (var binding in AnimationUtility.GetCurveBindings(clip))
    19.             {
    20.                 AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);
    21.  
    22.                 if (binding.propertyName.Contains("Joe") || binding.propertyName.Contains("Motion"))
    23.                 {
    24.                     EditorGUILayout.LabelField(binding.path + "/" + binding.propertyName + ", Keys: " + curve.keys.Length);
    25.                 }
    26.             }
    27.         }
    28.     }
    29. }