Skip to main content

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:

PythonMeaning
unreal.TakeForgeMode.EXACT_ROOT_MOTIONRoot follows the pelvis 1:1
unreal.TakeForgeMode.SMOOTHED_ROOT_MOTIONRoot follows a smoothed path
unreal.TakeForgeMode.IN_PLACETravel 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")