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.
  2. We’re making changes to the Unity Runtime Fee pricing policy that we announced on September 12th. Access our latest thread for more information!
    Dismiss Notice
  3. Dismiss Notice

Reading keyframe/curve data from Animator at runtime

Discussion in 'Animation' started by DerekMcKinley, May 3, 2019.

  1. DerekMcKinley


    Jun 24, 2014
    Hi community

    I know that this has been answered on other occasions and always the answer is no, but I would like to know if in the current versions of unity this is no longer a problem.

    I want to be able to read runtime the keyframes/curves of the current animation, specifically of a bone, for example the pelvis of the character, the final goal is to draw the route of the chosen bone corresponding to the animation that is being executed.

    Maybe there are restrictions for the type of animation, it can be a legacy/humanoid or any other, I just want to know if it is possible.

    Thank you for reading
  2. dibdab


    Jul 5, 2011
    it is possible for generic animations.

    you'll need the whole path for the bones, like
    bones [4] = bones [3] + "/" + prefix + "Neck";
    bones [5] = bones [4] + "/" + prefix + "Head";

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    6. public class getCRCurves : MonoBehaviour {
    8.     //gets animation curves for a bone from a clip
    9.     //for generic animations
    10.     public AnimationClip _clip;
    11.     public bool getCurves = true;
    13.     //check if the bone name in the clip equals
    14.     public string bone = "Hips";
    15.     [Header("Curves")]
    16.     [SerializeField] public AnimationCurve[] hip;
    17.     int i;
    18.     public bool doDebug = true;
    20.     void Start () {
    22.         if (getCurves) {
    24.             hip = new AnimationCurve[7];
    25.             var curveBindings = UnityEditor.AnimationUtility.GetCurveBindings (_clip);
    27.                 foreach (var curveBinding in curveBindings) {
    28.                     if (doDebug) Debug.Log (curveBinding.path + ", " + curveBinding.propertyName);
    30.                     if (curveBinding.path == bone && !curveBinding.propertyName.Contains ("LocalScale")) {
    31.                         hip [i] = AnimationUtility.GetEditorCurve (_clip, curveBinding);
    32.                         if (doDebug) Debug.Log ("curve> " + i + " " + curveBinding.path + ", " + curveBinding.propertyName);
    33.                         i++;
    34.                     }
    35.                 }
    36.             getCurves = false;
    37.         }
    38.     }
    39. }
    you might be able to do this for humanoid with

    animator.Play (animstate, -1, normalizedanimtime);

    like getting the localR of bones if they rotated a certain angle (or a certain amount of time has passed)
    Last edited: May 3, 2019
    Malbers, Genso_0 and DerekMcKinley like this.
  3. DerekMcKinley


    Jun 24, 2014

    @dibdab thank you very much for answering
    Now I can to draw the trajectory of the bone specified in this case "Hips", but I have noticed several problems.

    1. The trajectory that I draw is built by the list of 3d vectors of the base bone, is an incorrect way to graph the curves but it works, if someone knows how to graph animationCurves in 3d space please show me how I can do it, I made a search and I found nothing, should be using the mathematical formulas but I think this is not available.

    2. Animation curves only have the local rotation for the other parts of the body (hands, feet), that means that I can not choose their position in the time of the animation.

    I followed the path of breadcrumbs and found a post where you show how you animate a model superimposed on another using the curves, but I do not understand yet how you achieve this if the curves only offer local position, how do you make to match the positions?
    To match the trajectory of the curve and my character I had to move everything to the 0,0,0 position:D
  4. dibdab


    Jul 5, 2011
    you can have references of hands/feet and get their position runtime
    or calculate their position from the hip position, with the localrotations (probably)

    in that post the blue one is humanoid, the yellow one is generic (animated by curves)
    DerekMcKinley likes this.
  5. dibdab


    Jul 5, 2011
    found a way to extract curves from a humanoid animation
    [from this editor tool: AnimationCurveTools]
    with the getAllCurves method, which is obsolete, but works in 5.6

    the animation curves are in different order than the muscles and the root rotation is off yet*

    *okay, you just need to put the rootmotion curve values after SetHumanPose

    Code (CSharp):
    1. humanPoseHandler.SetHumanPose (ref humanPose);
    2. root.position = new Vector3(getAllCurves.sourceCurves[rootP[0]].Evaluate(timeNow), getAllCurves.sourceCurves[rootP[1]].Evaluate(timeNow), getAllCurves.sourceCurves[rootP[2]].Evaluate(timeNow));
    3. root.rotation = new Quaternion(getAllCurves.sourceCurves[rootR[0]].Evaluate(timeNow), getAllCurves.sourceCurves[rootR[1]].Evaluate(timeNow),getAllCurves.sourceCurves[rootR[2]].Evaluate(timeNow),getAllCurves.sourceCurves[rootR[3]].Evaluate (timeNow));

    Attached Files:

    Last edited: May 20, 2019
    DerekMcKinley likes this.
  6. DerekMcKinley


    Jun 24, 2014
    Great, I'm going to do some tests with this

  7. Eristen


    Jun 17, 2021
    Hi. I am not sure if this answers the question completely, but if all you need is the value of an animation curve then you can use this obscure fact

    "If you have a curve with the same name as one of the parameters in the Animator Controller, then that parameter takes its value from the value of the curve at each point in the timeline. For example, if you make a call to GetFloat from a script, the returned value is equal to the value of the curve at the time the call is made"

    See the link bellow
    Aoedipus and hareok2000 like this.
  8. Gekigengar


    Jan 20, 2013
    I am trying to create a custom animator, and need to know the object and the property value change of the object binded to it at runtime. But everything is only available through AnimationUtility class. I am thinking to bake the data in editor into my own Animation Clip for use in runtime, but that’s double the data! Ideally I can use Unity’s and access it from their’s!
  9. OmarVector


    Apr 18, 2018
    i know its old thread, but this solution for editor, not at runtime

    AnimationUtility.GetCurveBindings() is from Editor namespace and will be stripped in the build