How do I create a curve during post animation import

TLDR How do I create a curve during post animation import?
8460815--1123331--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!

You can do something like:

    public class AnimRootMotionExtractor : UnityEditor.AssetPostprocessor {
       void OnPostprocessAnimation(GameObject root, AnimationClip clip){
           Keyframe[] keys;
           keys = new Keyframe[3];
           keys[0] = new Keyframe(0.0f, 0.0f);
           keys[1] = new Keyframe(0.1f, 1.5f);
           keys[2] = new Keyframe(.5f,  2f);
           AnimationCurve curve = new AnimationCurve(keys);

           EditorCurveBinding binding = EditorCurveBinding.FloatCurve("", typeof(UnityEngine.Animator), "Joe");
           AnimationUtility.SetEditorCurve(clip, binding, curve);
       }
   }

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

public class ClipInfo : EditorWindow
{
    private AnimationClip clip;

    [MenuItem("Window/Clip Info")]
    static void Init()
    {
        GetWindow(typeof(ClipInfo));
    }

    public void OnGUI()
    {
        clip = EditorGUILayout.ObjectField("Clip", clip, typeof(AnimationClip), false) as AnimationClip;

        EditorGUILayout.LabelField("Curves:");
        if (clip != null)
        {
            foreach (var binding in AnimationUtility.GetCurveBindings(clip))
            {
                AnimationCurve curve = AnimationUtility.GetEditorCurve(clip, binding);

                if (binding.propertyName.Contains("Joe") || binding.propertyName.Contains("Motion"))
                {
                    EditorGUILayout.LabelField(binding.path + "/" + binding.propertyName + ", Keys: " + curve.keys.Length);
                }
            }
        }
    }
}