The problem I kept running into: shoot 6 takes in the same session with the same actor and somehow every clip has the hip bone sitting at a slightly different world-space height. Actor stands a little differently at calibration, the suit vest shifts, capture software picks a slightly different reference pose. Small variance, but in-engine when you transition between clips the root lurches up or down at the cut.
Wrote a script that goes through every action in the .blend, finds the Z location FCurve for the root/hip bone, samples it at a reference frame, and shifts every keyframe uniformly by the delta to a target baseline. Not stretching the animation, just translating the whole Z curve up or down.
import bpy
HIP_BONE = 'mixamorig:Hips' # update to match your rig
TARGET_HEIGHT = 1.0 # world-space Z at rest, in meters
REF_FRAME = 1 # frame to sample for baseline height
def normalize_hip_heights():
armature = bpy.context.object
if not armature or armature.type != 'ARMATURE':
print('Select an armature first.')
return
for action in bpy.data.actions:
bone_path = 'pose.bones["{}"].location'.format(HIP_BONE)
z_curve = next(
(fc for fc in action.fcurves
if fc.data_path == bone_path and fc.array_index == 2),
None
)
if z_curve is None:
continue
ref_z = z_curve.evaluate(REF_FRAME)
delta = TARGET_HEIGHT - ref_z
if abs(delta) < 0.005:
print('[skip] {}: already near target ({:.4f}m)'.format(action.name, ref_z))
continue
for kp in z_curve.keyframe_points:
kp.co[1] += delta
kp.handle_left[1] += delta
kp.handle_right[1] += delta
z_curve.update()
print('[ok] {}: shifted {:+.4f}m'.format(action.name, delta))
normalize_hip_heights()
Assumptions baked in:
HIP_BONE to match your naming: Hips, Root, mixamorig:Hips, etc.What it doesn't fix: variance in hip height throughout the take from actor posture drift or floor contact differences. This is purely a per-action origin offset correction, the relative motion inside each clip stays untouched.
One thing I'm unsure about: whether sampling a median over the first 10–15 frames would be more robust than a single reference frame. Some takes have a small settle at frame 1 before the actor finds their natural stance, which skews the baseline. Anyone tackled this and found a better sampling approach?