How to dynamically set animation key frame value?

I created animation clips like the image shown below, but I need to revise the Position.y value dynamically by script. Therefore I am wondering if there is a method for me to revise the Position.y value. Thank you very much.

1 Like

In the editor, you can use the UnityEditor.AnimationUtility class to get access to the curves of an AnimationClip and modify their keyframes however you like.

At runtime, you can’t. AnimationClip.SetCurve might work, but there is no GetCurve so you can’t just modify a single keyframe of an existing curve unless you get it in the editor and serialize it separately from the clip.

I would just use a script to control the object instead. That way you get full control.

Thanks a lot! I know there are ways to edit the curve, but this is not the function I want. I will switch to controlling the object instead. :slight_smile:

@Kybernetik woah so we can’t modify a single keyframe of an animation curve at runtime unless that keyframe has already been set as a variable in the editor?

Probably not even that. As I said, AnimationClip.SetCurve might work.

If anyone wants I wrote a simple helper class for basic keyframe changing functionality.

using UnityEditor;
using UnityEngine;

public class AnimationCurveChanger : MonoBehaviour {
    public static void UpdateAnimationCurveWithSingleKeyFrame(GameObject animatorGameObject, string animationClipName, string propertyPath, string propertyName, float time, float value) {
        UpdateAnimationCurveWithMultipleKeyFrames(animatorGameObject, animationClipName, propertyPath, propertyName, new float[] { time }, new float[] { value });
    }

    public static void UpdateAnimationCurveWithMultipleKeyFrames(GameObject animatorGameObject, string animationClipName, string propertyPath, string propertyName, float[] times, float[] values) {
        // Get all animation clips from animatorGameObject, these are the dropdown menu options in the Animator.
        // For example: when creating a button animator these will be named by default - Normal, Pressed, Highlighted, Disabled
        AnimationClip[] animationClips = AnimationUtility.GetAnimationClips(animatorGameObject);
        for (int i = 0; i < animationClips.Length; i++) {
            // Find the relevant animationClip by name
            if (animationClips[i].name == animationClipName) {
                // Get all curve bindings, these are the rows in the Animator.
                // For example: Button : Scale.x
                EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(animationClips[i]);
                for (int j = 0; j < curveBindings.Length; j++) {
                    // Find the relevant curve binding row
                    if (curveBindings[j].path == propertyPath && curveBindings[j].propertyName == propertyName) {
                        // Modify the curve
                        AnimationCurve editorCurve = AnimationUtility.GetEditorCurve(animationClips[i], curveBindings[j]);
                        AnimationCurve newCurve = new AnimationCurve();
                        for (int l = 0; l < times.Length; l++) {
                            newCurve.AddKey(times[l], values[l]); ;
                        }
                        // Set the curve, thus "saving" it to the scene
                        AnimationUtility.SetEditorCurve(animationClips[i], curveBindings[j], newCurve);
                    }
                }
            }
        }
    }
}

You can call this function like so:

AnimationCurveChanger.UpdateAnimationCurveWithSingleKeyFrame(RelevantGameObject, "Normal", "cornerIcon", "m_SizeDelta", 0, 20);

But this uses UnityEditor classes…is this available for runtime … i mean as app…when run outside of editor ?