dibdab
January 10, 2019, 6:24pm
1
I would like to use hip curve’s root motion data
(for playing it regularly and/or at a normalized time of the clip)
and on a humanoid that has root motion switch off (something like a requirement)
probably could get the hip data when playing the anim clip, not sure
probably this function did that, which is now obsolete
this says on any animated properties (but is there a way to get that data?)
this sound good, but questionable now if will be able to use it
Thus array of keyframes is returned instead of a singular curve object.
public static ObjectReferenceKeyframe[] GetObjectReferenceCurve(AnimationClip clip, EditorCurveBinding binding);
there has been some discussions about this, but didn’t find an answer to
to don’t want to remove or add curve
here’s how to add rootmotion
Hi guys, so I have a character setup, and the parent object it’s actually an empty game object, consist with the character model as a child in it. And all the scripting are on the parent object (moving, jumping, edge grab, etc). The problem is, the edge climbing animation are using root motion to translate across the Y-axes, but because the mecanim character is the child object, the Y position snaps back after climbing animation is done. Is there a way to apply the climbing root motion to the pa…
Hi, I have a question on apply root motion.
I have a model in generic rig with ‘Hips’ as the root node.
and I made an animation with Unity Animation Window that moves the hips.
Now I want the translation on hips to be used by Animator’s ‘Apply Root Motion’;
I checked other imported animation, they have animated properties of ‘Animator.Motion T’ and ‘Animator.Motion Q’, the curves looks similar with ‘Hips’.
So, my question is, if I duplicate the ‘Hips.localPosition’ and ‘Hips.localRotation’,…
but MecanimAnimator says
so MotionT and MotionQ is there somewhere, isn’t it
I’m not sure if this example.cs is still working or if would get hip’s rootmotion
okay, so i’ve seen a few posts on this topic, but they always end with, “oh i figured it out”, and no explanation how. i’m trying to get a char to recover from ragdoll. i can copy all the transforms from the ragdoll to the instantiated character, but can’t figure out how to lerp to the beginning of an animation. everything i try just makes them snap directly to the animation. i believe i need to use mathf.LerpAngle, but don’t know how to sample the transforms for the animation frame i need? than…
1 Like
_clip is the clip you’re looking at and rootMotionNodeName would be your hip/root motion joint’s path:
var curveBindings = UnityEditor.AnimationUtility.GetCurveBindings(_clip);
foreach (var curveBinding in curveBindings)
{
if (curveBinding.path == rootMotionNodeName)
{
//Debug.Log(curveBinding.path + ", " + curveBinding.propertyName);
var editorCurve = UnityEditor.AnimationUtility.GetEditorCurve(_clip, curveBinding);
}
}
dibdab
January 10, 2019, 11:16pm
3
hey, thanks.
maybe this could lead to something.
one thing. the clip cannot be humanoid, it must be generic.
if humanoid, curveBinding.path returns empty.
for the record, this Debug.Log(curveBinding.path + ", " + curveBinding.propertyName);
looks like this for RunForward_NtrlFaceFwd.fbx
now would need this var editorCurve turn into AnimationCurve what it is, but that is not so simple either
ah, yeah, if just AnimationUtility.GetEditorCurve without UnityEditor I’m getting some curve
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class getACurves : MonoBehaviour {
public AnimationClip _clip;
public string boneName;
public AnimationCurve curve;
void Start () {
var curveBindings = UnityEditor.AnimationUtility.GetCurveBindings(_clip);
foreach (var curveBinding in curveBindings)
{
//Debug.Log(curveBinding.path + ", " + curveBinding.propertyName);
if (curveBinding.path == boneName)
{
curve = AnimationUtility.GetEditorCurve(_clip, curveBinding);
Debug.Log("curve> " + curveBinding.path + ", " + curveBinding.propertyName);
}
}
}
}
would need to filter them by propertyName yet
1 Like
Ahh, it hadn’t occurred to me that root motion might work differently for humanoid rig clips as I don’t use any of the built in mecanim retargeting.
So given the root motion node’s animation curves from above, to get total root motion for a clip at time t, I do something along the lines of:
for curve localPosition.x, localPosition.y, etc.
p0 = evaluate curve at time 0 (AnimationCurve::Evaluate)
p1 = evaluate curve at time t
motion = p1 - p0
Same deal with rotation, etc. I also strip out a bunch of unneeded curves including root motion on import, storing stripped animation clip, root motion curves and other metadata in another asset which I use internally with custom Playables mixer. Requires more scaffolding around your animation setup but also allows complete control over how root motion is treated.
dibdab
January 11, 2019, 2:17pm
5
yeah, it can be usable for many thing: anim rootmotion modif, between-states, poses, animating etc
I guess unity’s Kinematica does this too, first it extracts all curves from the clips
humanoid/generic is not a problem with mixamo 'cause the gen version got the same animation and same root curves
the hip/root curves
and if I use these curves to move a transform
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moveByCurves : MonoBehaviour {
public getACurves getACurves;
public Transform mover;
public float time;
//for root there's 10 curves: rotation[4], position[3], scale[3]
//all other bones 7: rotation[4], scale[3]
public int curvN = 10;
int i;
public bool isRoot;
void Update () {
time = Time.time;
if (isRoot) {
mover.rotation = new Quaternion (
getACurves.curve [0].Evaluate (time),
getACurves.curve [1].Evaluate (time),
getACurves.curve [2].Evaluate (time),
getACurves.curve [3].Evaluate (time)
);
mover.position = new Vector3 (
getACurves.curve [4].Evaluate (time),
getACurves.curve [5].Evaluate (time),
getACurves.curve [6].Evaluate (time)
);
}
if (!isRoot) {
mover.localRotation = new Quaternion (
getACurves.curve [0].Evaluate (time),
getACurves.curve [1].Evaluate (time),
getACurves.curve [2].Evaluate (time),
getACurves.curve [3].Evaluate (time)
);
}
}
}
then it looks alright
but doesn’t match up with legs
which might be a localRotation (*not rotation) issue
will test later
2 Likes
dibdab
January 11, 2019, 2:25pm
6
okay, had to check it now
it is localRotation
updated the script above
3 Likes
dibdab
July 26, 2020, 11:53pm
7
used these scripts to get and modify root motion curves
frog had only one jump, and wanted to have blendtree of short and long jump
the original animation has been rotated (not lookin the direction of the “T-pose”)
so had used just the root curves (and added rotation)
and other bones has been played by animator (sync.state)
6135083–669134–getBonesPath.cs (4.46 KB)
6135083–669137–playBonesCurves.cs (2.57 KB)
2 Likes
sorry if I write under this old post. I have a list of AnimationCurve. Can I merge them to export to fbx to use this new animation?
bobadi
January 16, 2021, 8:46pm
9
there’s no script/package that would do that to my knowledge.
you can record the animation being played in unity (like w playBonesCurves.cs)
there’s couple possibilities for that:
Scene Motion Capture (.anim)
Final IK’s baker (.anim)
Skele’s DAE exporter (.anim > .dae)
UnityTech’s fbx exporter
Thanks guys for digging into this, will be much helpfull in our case !
I’m binding this into the validate step so I can extract the curves to use while in play mode.