Python
Editor Python reaches the library as unreal.TakeForgeLibrary; function names
become snake_case. Run scripts from Tools → Execute Python Script, the
Output Log's Python mode, or -run=pythonscript in CI.
Return convention: every mutating function hands back a tuple with success first and the error message last - on failure too, so a failed call always explains itself:
ok, err = unreal.TakeForgeLibrary.mirror(seq)
if not ok:
unreal.log_error(err)
Functions with extra results slot them in between, e.g.
ok, markers_added, err = .... Pure queries (get_average_speed,
get_extracted_root_motion) return their value directly.
Functions
retarget_takes
ok, created, err = unreal.TakeForgeLibrary.retarget_takes(
sequences, target_skeleton, retargeter, suffix, target_path)
Retargets the takes onto another skeleton. Pass exactly one of
target_skeleton (bone-name matching, for rigs that share names) or
retargeter (chain-mapped, for rigs that differ); the retargeter wins if
both are given. target_path empty writes each output beside its source, and
created holds the new sequences so cleanup can be chained onto them.
Skeleton mode needs the editor UI and returns an error under
-run=pythonscript; use IK Retargeter mode for headless batches. See
Retarget Takes.
apply_root_motion
ok, err = unreal.TakeForgeLibrary.apply_root_motion(sequence, mode)
Transfers pelvis travel to the root bone, or removes it for the in-place mode.
mode is one of:
| Python | Meaning |
|---|---|
unreal.TakeForgeMode.EXACT_ROOT_MOTION | Root follows the pelvis 1:1 |
unreal.TakeForgeMode.SMOOTHED_ROOT_MOTION | Root follows a smoothed path |
unreal.TakeForgeMode.IN_PLACE | Travel removed from the animation |
Also applies sync markers and speed curves per your settings, and sets
bEnableRootMotion on root-motion modes.
make_loopable
ok, err = unreal.TakeForgeLibrary.make_loopable(sequence)
Blends the clip's end into its start pose (window = Loop Blend Frames setting). Root bone excluded so root-motion travel survives.
align_travel_direction
ok, err = unreal.TakeForgeLibrary.align_travel_direction(sequence)
Rotates the take around its start point so net travel runs along the configured forward axis. Fails on takes with under 10 cm of travel.
rezero_to_origin
ok, err = unreal.TakeForgeLibrary.rezero_to_origin(sequence, zero_height, zero_yaw)
Shifts the take so the root's first frame sits at the origin - XY always, height and yaw per the flags. See Start at Origin.
mirror
ok, err = unreal.TakeForgeLibrary.mirror(sequence)
Bakes a left↔right mirrored version: pose reflected across the rig's symmetry
plane, _l/_r bone pairs, foot sync markers, and notify names swapped. See
Mirror.
trim_to_range
ok, err = unreal.TakeForgeLibrary.trim_to_range(sequence, start_frame, end_frame)
Keeps only frames [start_frame, end_frame].
retime_to_speed
ok, err = unreal.TakeForgeLibrary.retime_to_speed(sequence, target_speed_cm_s)
Sets Rate Scale so the clip plays at the target speed; rescales the
RootMotion_Speed curve to stay truthful.
adjust_motion
ok, err = unreal.TakeForgeLibrary.adjust_motion(sequence, speed_factor, amplitude_factor)
Playback-speed multiplier and motion-amplitude scaling around the clip-average
pose, for tuning idle-like takes. Both 1.0 = no change. See
Adjust Motion.
isolate_bones
ok, err = unreal.TakeForgeLibrary.isolate_bones(sequence, keep_bones, others_hold_first_frame)
Keeps animation only on keep_bones and their descendants; every other bone
track is removed (reference pose) or, with others_hold_first_frame=True,
replaced by a constant first-frame pose. The root counts like any bone -
include it to keep root motion. See Isolate Bones.
strip_bones
ok, err = unreal.TakeForgeLibrary.strip_bones(sequence, remove_bones, hold_first_frame)
The opposite of isolate_bones: cleans animation from remove_bones and
their descendants while every other bone keeps its animation.
graft_bones
ok, err = unreal.TakeForgeLibrary.graft_bones(
target, source, bones,
source_start_frame, source_end_frame,
target_start_frame, target_end_frame, blend_frames, add_on_top)
Splices source's movement onto target for the given branches, in local
bone space; the source window is retimed onto the target window and fades
over blend_frames at the edges. With add_on_top=True the source's
deviation from its own window-average pose is layered onto the target
instead of replacing it. Both sequences must share a skeleton. See
Graft Bones.
reverse_take
ok, err = unreal.TakeForgeLibrary.reverse_take(sequence)
Bakes the take playing backwards - keys, curves, notifies, and markers all reverse; the root re-anchors to the original start. See Reverse.
find_best_loop
ok, start, end, mismatch, err = unreal.TakeForgeLibrary.find_best_loop(sequence, min_loop_seconds)
Finds the frame window with the best endpoint pose/velocity match - analysis
only; compose with trim_to_range + make_loopable to apply. See
Find Best Loop.
speed_ramp
ok, err = unreal.TakeForgeLibrary.speed_ramp(sequence, [unreal.Vector2D(frame, speed), ...])
Bakes a variable playback speed from (frame, speed) control points - tracks, curves, notifies, and markers all follow the time warp. See Speed Ramp.
foot_lock
ok, err = unreal.TakeForgeLibrary.foot_lock(
sequence, lock_left, lock_right, blend_frames, max_correction_cm,
ground_snap=0, ground_offset_cm=0.0, flatten_sole=False)
Pins each foot during its ground-contact windows via an analytic two-bone leg IK, feathered at the window edges.
ground_snap additionally puts the planted feet on the floor: 1 shifts
the whole take by one constant (no deformation), 2 IKs each plant down
individually and refuses slopes. flatten_sole levels the sole during
contact. ground_offset_cm raises or lowers the floor the snap targets, in
both modes - a destination, not an increment. See Foot Lock.
measure_ground_contact
ok, offset_cm, spread_cm, windows = unreal.TakeForgeLibrary.measure_ground_contact(sequence)
How far the planted feet sit above (+) or below (-) the floor, how much
the individual contacts disagree (a slope reads as a large spread), and how
many contact windows were measured. Read it before deciding whether a take
needs ground_snap at all:
ok, offset, spread, n = unreal.TakeForgeLibrary.measure_ground_contact(seq)
if ok and abs(offset) > 1.0:
mode = 1 if spread < 15.0 else 0 # one floor, or a slope to leave alone
unreal.TakeForgeLibrary.foot_lock(seq, True, True, 3.0, 30.0, ground_snap=mode)
stitch_takes
ok, err = unreal.TakeForgeLibrary.stitch_takes(target, second, blend_frames)
Appends second after target with a crossfaded transition; second's root
motion is re-based to continue from where target ends, and its notifies,
markers, and curve keys are appended time-shifted. Same skeleton required.
See Stitch Takes.
smooth_bones
ok, err = unreal.TakeForgeLibrary.smooth_bones(
sequence, bones, frame_ranges, smoothing_frames, blend_frames)
Zero-phase Gaussian smoothing of the given branches. frame_ranges is a list
of unreal.IntPoint(start, end) windows (inclusive) - pass [] to smooth the
whole clip. smoothing_frames is the Gaussian radius, blend_frames the fade
at each window edge. See Smooth Bones.
add_foot_sync_markers
ok, markers_added, err = unreal.TakeForgeLibrary.add_foot_sync_markers(sequence)
Detects foot plants and places foot_l / foot_r sync markers on the
FootSync notify track - just the markers, no other processing. Replaces
markers previously placed by TakeForge; foot bones and the contact height
fraction come from Settings.
add_footstep_notifies
ok, notifies_added, err = unreal.TakeForgeLibrary.add_footstep_notifies(
sequence, left_notify, left_notify_name, right_notify, right_notify_name)
Places a footstep anim notify at every detected foot plant on a Footsteps
notify track (replacing notifies previously placed there). Per foot: an
instance of the given AnimNotify class, or - when the class is None - a
named skeleton notify with the given name. Pass the same class/name for both
feet for a single-notify setup. Frame-0 contacts are initial state, not
steps. See Footstep Notifies.
sync_ik_bones
ok, err = unreal.TakeForgeLibrary.sync_ik_bones(sequence, include_hands)
Bakes ik_foot_l / ik_foot_r, and with include_hands the ik_hand_*
bones, so each follows the real bone it shadows. Retargeting from a rig
without IK bones leaves them at the reference pose, which makes Foot
Placement drag the legs in game while the clip still previews correctly.
Rewrites the sequence in place. See Sync IK Bones.
add_motion_matching_curves
ok, err = unreal.TakeForgeLibrary.add_motion_matching_curves(
sequence, enable_warping=True, constant_speed=False,
constant_speed_value=1.0, contact_curves=False)
Writes enable_warping (flat 1, or 0 when enable_warping is false),
movedata_speed (measured per frame, or constant_speed_value everywhere
when constant_speed is true) and the gait phase curve; with
contact_curves, also contact_l / contact_r. Curve names come from
Settings. Edits the take in place. See
Motion Matching Curves.
normalize_track_order
ok, err = unreal.TakeForgeLibrary.normalize_track_order(sequence)
Rewrites all bone tracks in skeleton hierarchy order (root first). Repairs assets whose out-of-order tracks make compression silently destroy root motion. All mutating TakeForge functions do this automatically on output.
get_extracted_root_motion
cm = unreal.TakeForgeLibrary.get_extracted_root_motion(sequence)
Net root motion the runtime would extract over the whole clip - what a
montage or the capsule receives. Compare with get_average_speed to tell
asset-settings problems from missing travel. Read-only.
get_average_speed
speed = unreal.TakeForgeLibrary.get_average_speed(sequence)
Average travel speed in cm/s (net pelvis displacement / duration); 0.0 when
it can't be measured. Read-only.
Recipes
Process a whole session folder
import unreal
SRC = "/Game/Mocap/Session04"
for path in unreal.EditorAssetLibrary.list_assets(SRC):
asset = unreal.load_asset(path)
if not isinstance(asset, unreal.AnimSequence):
continue
# non-destructive: duplicate, then process the copy
dup_path = path.split(".")[0] + "_InPlace"
dup = unreal.EditorAssetLibrary.duplicate_asset(path.split(".")[0], dup_path)
ok, err = unreal.TakeForgeLibrary.apply_root_motion(
dup, unreal.TakeForgeMode.IN_PLACE)
if ok:
unreal.TakeForgeLibrary.make_loopable(dup)
else:
unreal.log_warning(f"{path}: {err}")
Mirror every strafe in a folder
import unreal
for path in unreal.EditorAssetLibrary.list_assets("/Game/Mocap/Strafes"):
seq = unreal.load_asset(path)
if isinstance(seq, unreal.AnimSequence) and "_Left" in seq.get_name():
base = path.split(".")[0]
dup = unreal.EditorAssetLibrary.duplicate_asset(
base, base.replace("_Left", "_Right"))
ok, err = unreal.TakeForgeLibrary.mirror(dup)
if not ok:
unreal.log_warning(f"{path}: {err}")
Audit take speeds into a table
import unreal
for path in unreal.EditorAssetLibrary.list_assets("/Game/Mocap"):
seq = unreal.load_asset(path)
if isinstance(seq, unreal.AnimSequence):
speed = unreal.TakeForgeLibrary.get_average_speed(seq)
print(f"{seq.get_name():40s} {speed:7.1f} cm/s")