How can I add a new created AnimationCurve to an AnimationClip by Script?
This is about the float curves that update Animator Parameters with identical names.
I can do this by Hand using the Animations tab of the Animation Import Settings.
Unity Documentation: Animation Curves on Imported Clips
But for an InspectorTool on a StateMachineBehaviour I would need to add and edit new curves by script (and edit existing ones).
I have been able to get all existing curves of the used animation clip.
Unfortunately I didn’t find a possibility to distinguish between the normal bone animation curves and the parameter curves. Luckily I could work around this by checking their names.
When I add a Curve to the animationClip it is in the complete list - so obviously that works. But I want to add a Parameter Curve…
Anyone an Idea?
After some time with IL-Spy I finally got it working like this:
The Parameter AnimationCurves are stored into the metafiles of the imported FBX files - so to get the changes permanently it is necessary to work with the SerializedProperty m_ClipAnimations of the Modelimporter.
I needed this in a CustomInspector of a StateMachineBehaviour - If you don’t skip Step 1.
-
Get the used AnimationClip of the
inspected StateMachineBehaviour with
Unitys
[StateMachineBehaviourContext][1]
-
Get the instance of the used
ModelImporter for that AnimationClip
and create the SerializedObject of
it.
-
Now this is the SerializedProperty of the AnimationClip used by this StateMachineBehaviour - to get the Parameter driving AnimationCurves search for the property “curves”.
protected StateMachineBehaviour m_behaviour;
protected StateMachineBehaviourContext[] m_context;
protected AnimatorController m_animController;
protected string m_assetPath;
protected AnimationClip m_clip;
protected ModelImporter m_importer;
protected SerializedObject m_importerSObj;
public virtual void OnEnable()
{
// STEP 1
m_behaviour = target as StateMachineBehaviour;
m_context = AnimatorController.FindStateMachineBehaviourContext(m_behaviour);
m_context = AnimatorController.FindStateMachineBehaviourContext(m_behaviour);
if (m_context != null)
{
// animatorObject can be an AnimatorState or AnimatorStateMachine
m_animController = m_context[0].animatorController;
AnimatorState state = m_context[0].animatorObject as AnimatorState;
if (state != null)
{
m_clip = state.motion as AnimationClip;
if (m_clip != null)
{
// STEP 2
m_assetPath = AssetDatabase.GetAssetPath(m_clip);
m_importer = (ModelImporter)AssetImporter.GetAtPath(m_assetPath);
m_importerSObj = new SerializedObject(m_importer);
SerializedProperty clipProp = m_importerSObj.FindProperty(“m_ClipAnimations”);
for (int i = 0; i < m_importer.clipAnimations.Length; i++)
{
if (m_clip.name == m_importer.clipAnimations*.name)*
{
//STEP 3
clipProp.GetArrayElementAtIndex(i); // the AnimationClip Property
}
}
}
}
}
}
[1]: Unity - Scripting API: StateMachineBehaviourContext