UE-MCP native animation workflow
Create quality animation from measured pose constraints, not guessed control
angles. Control names, local axes, palm axes, handedness, and scale are
properties of the selected rig. Discover them again for every unfamiliar rig;
never paste values from another rig or negate a left-side Euler pose to make a
right-side pose.
Focused skeletal mesh weighting
Use the existing skeleton-edit actions for bone creation, removal, reparenting,
and reference-pose changes. For a small, explicit skin-weight correction:
- Call
asset(action="list_skeleton_bones", assetPath=<mesh>, includeTransforms=false) and use the returned names exactly.
- Call
asset(action="read_skeletal_mesh_skin_weights", assetPath=<mesh>, lodIndex=0, vertexIndices=[...]). Keep each read to the selected source
vertex IDs; the action caps a call at 256 vertices.
- Call
asset(action="set_skeletal_mesh_skin_weights", assetPath=<mesh>, lodIndex=0, edits=[{vertexIndex, influences:[{boneName, weight}]}]) with the
complete replacement influence set for every selected vertex. Inspect the
returned before and after: Unreal normalizes and prunes the list, and
stores source weights as uint16 values. The render buffer may quantize again
to 8-bit unless the LOD enables high-precision skin weights.
- Open the rebuilt mesh with
editor(action="open_asset", assetPath=<mesh>)
and capture the asset editor at the reference pose and useful preview poses.
Re-read the same selected vertices before moving on.
The weight setter edits one existing source LOD and profile, saves only when a
selected value changed, and leaves all unlisted vertices, LODs, and profiles
alone. It does not infer bones, fit a mesh, or auto-rig a character.
Required loop
- Call
project(action="get_status"); verify the intended project and editor.
- Establish the character's authoring baseline before editing clips. Search
for a Control Rig already bound to the target mesh/skeleton and inspect it
with
read_control_rig_hierarchy and read_control_rig_graph. It must have
the controls, Forward Solve, and Backward Solve required for the intended
edits. If the project or character has no suitable rig, create one first
with the bundled Epic 5.8 controlrig actions (epic_create,
epic_import_bones_from_asset, epic_add_control, deliberate Forward Solve
nodes/links, and epic_add_backward_solve_graph), then save the exact rig
with asset(epic_save_assets). epic_create alone creates no imported
bones, authored controls, or solver wiring. Run an unchanged
source-to-controls-to-bones round trip on the exact production mesh. Do not
begin production work on an unverified or merely name-compatible rig.
- Resolve the source AnimSequence, mesh, skeleton, verified Control Rig, and
frame rate.
When IK/retarget assets are part of the job, use
read_ik_rig and
read_ik_retargeter first. On UE 5.8 use configure_ik_rig for validated
roots, ancestry-valid chains, concrete goals, solver connections and
effectors; use configure_ik_retargeter for the default op stack, source and
target rig assignment to every op, auto/manual mappings, preview meshes, and
a named retarget pose. Read both assets back after saving. A chain's goal
string is not proof that a goal or solver exists.
- Create a versioned session with
begin_control_rig_edit. Use a unique
LevelSequence path and bindingTag, an end-exclusive frame range, and
onConflict="error". Use rigMode="asset" for a project rig or "fk" only
when generated FK controls are intentional. The source must be non-additive
and mesh-compatible; flatten an additive clip against its intended base
first. layered controls the session layer, not an additive source base.
A finite non-zero source RateScale is compensated in Sequencer so the raw
timeline maps once without modifying the source asset; zero is rejected.
- Call
read_control_rig_edit at rest, transitions, extrema, and end in both
local and global space. Here global is rig/global (normally mesh
component) space, not actor world space.
- Inspect every control's
controlType, animatable, and enum metadata. Write
scalars with the matching set_bool, set_float, or set_int; enum values
must come from enumOptions. Never write animatable=false controls.
- Define anatomical component-space targets, then solve proximal to distal:
shoulder/upper arm, elbow pole and bend, forearm direction, wrist, palm
normal, then secondary motion. For a wave, the forearm must rise, the wrist
must sit above the elbow/near the shoulder region, and the probed palm normal
must face the intended viewer before wrist oscillation is added.
- When an axis is uncertain, make an immutable probe session. Apply a small
positive and negative rotation to one local axis at one fixed frame, bake,
and inspect the resulting component-space shoulder/forearm/hand landmarks
with
analyze_animation. Probe the right side separately; mirrored parents
or negative scale can reverse anatomical meanings. Preserve the full scale
read from the control.
- Apply absolute
set_keys transforms with finite normalized quaternions,
complete translation/rotationQuaternion/scale payloads, and strictly
increasing frames. Preserve translation and scale unless intentionally
editing them. If the source bake has dense keys, key every affected frame;
sparse keys will not replace the intervening source motion. Apply related
controls and scalar switches in one transaction.
For a fixed contact, use contact_lock in the same operation batch. Supply a
keyable translatable driver, optional driven bone/socket, inclusive frame
range, component-space target, optional pole/stabilizer controls, and
position/rotation tolerances. The session must contain one source animation
section. The bridge samples it per frame, writes dense smooth-edged keys, and
transactionally reads back the driver and stabilizers. A driven bone/socket
returns verification=bake_and_analyze_required; bake, analyze every
constrained frame, and reject the output if its residual misses the motion's
acceptance tolerance. To follow a moving source bone/socket, set
targetReference; omit target to preserve the first-frame relative
transform, or provide target as an explicit transform in the reference's
space. This is the generic two-hand/hand-to-prop relationship primitive. FK
contacts whose translation is ignored by skeleton
retargeting use a local rotation-chain solve and report
solver=fk_rotation_chain; that path requires a driven bone and does not
accept stabilizers. Position-only locks leave the driven control orientation
unkeyed. The bridge does not guess the driver, pole, foot roll, friction,
joint limits, or pelvis compensation.
- Read back the edited frames in local and global space. Reject elbow flips,
discontinuities, wrong forearm direction, wrong palm normal, or unexpected
changes outside the edited chain before baking.
- Bake to a new versioned AnimSequence with
bake_control_rig_edit,
reduceKeys=false, and onConflict="error". Never overwrite source,
another iteration's session, or prior approved output assets.
Validation and visual review
Run analyze_animation on source and output using the same mesh, explicit
frames, and bones. Include root, pelvis, the complete edited chain, feet,
opposite side, and any controls/bones expected to remain unchanged. Write its
native manifest.json and samples.ndjson beneath
Saved/Codex/AnimationQA.
Check numeric integrity, invalid transforms, selected-bone bounds, root
displacement/speed, and loop seam metrics. Derive gesture-specific checks from
component transforms: shoulder-relative wrist height, elbow-to-wrist vector,
elbow angle/plane stability, probed palm-normal alignment, speed/acceleration,
direction changes, and drift in untouched bones. Numeric samples are the source
of truth; screenshots are the human visual gate.
Use the analyzer's rateScale, effectiveDurationSeconds, and per-notify
rawTriggerTimeSeconds / effectiveTriggerTimeSeconds fields when validating
gameplay release timing. Effective times use the asset-rate magnitude and are
null when the asset rate is zero.
For an exact native frame capture, without Computer Use or Python:
editor(action="open_asset", assetPath=<baked_anim>).
editor(action="find_object") for className="AnimSingleNodeInstance",
nameContains="AnimPreviewInstance", world="any"; select the match under
the current AnimationEditorPreviewActor.
- In one
editor(action="invoke_object_functions") call, invoke SetPlaying with
bIsPlaying=false, then SetPosition with
InPosition=frame*rateDenominator/rateNumerator and
bFireNotifies=false on that object path.
- Open the asset again to focus its window and call
editor(action="capture_screenshot", target="window").
- Capture start, entry, both extrema, exit, and end with a consistent view.
Keep versioned V&V fixtures for a from-scratch gesture, full-body IK authoring,
a retarget between known skeletons, a copied animation modified through IK plus
its pole target, a bone/socket contact with an unrelated simultaneous edit, and
edge cases covering mirrored/negative scale, dense keys, additive-source
rejection/flattening, layered sessions, scalar enums, root motion, loops, and
short clips.
The loop generalizes beyond humanoid arms. Re-discover the rig mapping, then
express legs as hip/knee-pole/foot/contact constraints; spine and head as
arc/twist/aim constraints; tails, tentacles, and ropes as length-preserving
chain curves with delayed phase; and props or mechanisms as pivot, attachment,
contact, and clearance constraints. Only control/bone names, axes/signs,
mirrored scale, limits, and motion constraints are rig-specific.
Compatibility and endpoint rule
The four Control Rig session actions, configure_ik_rig,
configure_ik_retargeter, and contact_lock are UE 5.8 only and return
unsupported_engine_version on older engines; do not invent a reflected or
raw-bone fallback. Legacy IK create/read behavior is unchanged.
analyze_animation is cross-version through the native APIs in the compiled
engine. See the public
Native Control Rig Animation
guide for full call shapes and fixture guidance.
Edit ranges are [startFrame, endFrameExclusive). The bridge keeps an internal
support frame for Unreal's exact-duration export sample without making the
exclusive end authorable. Validate the last visible frame and exact-duration
sample separately. A non-looping endpoint must hold the intended final pose
without an adjacent-frame teleport or rotation jump; a looping endpoint must
pass the requested seam check. A large endpoint discontinuity fails the bake.
1---2name: ue-mcp-animation3description: Use when creating, modifying, retargeting, rigging, constraining, or validating skeletal animation through UE-MCP. Covers native UE 5.8 IK Rig and Retargeter authoring, the Control Rig begin/read/apply/bake loop, generic contact locks, per-rig anatomical and mirrored-axis discovery, quaternion keying, deterministic bone analysis, and exact fixed-frame Unreal capture.4---56# UE-MCP native animation workflow78Create quality animation from measured pose constraints, not guessed control9angles. Control names, local axes, palm axes, handedness, and scale are10properties of the selected rig. Discover them again for every unfamiliar rig;11never paste values from another rig or negate a left-side Euler pose to make a12right-side pose.1314## Focused skeletal mesh weighting1516Use the existing skeleton-edit actions for bone creation, removal, reparenting,17and reference-pose changes. For a small, explicit skin-weight correction:18191. Call `asset(action="list_skeleton_bones", assetPath=<mesh>,20 includeTransforms=false)` and use the returned names exactly.212. Call `asset(action="read_skeletal_mesh_skin_weights", assetPath=<mesh>,22 lodIndex=0, vertexIndices=[...])`. Keep each read to the selected source23 vertex IDs; the action caps a call at 256 vertices.243. Call `asset(action="set_skeletal_mesh_skin_weights", assetPath=<mesh>,25 lodIndex=0, edits=[{vertexIndex, influences:[{boneName, weight}]}])` with the26 complete replacement influence set for every selected vertex. Inspect the27 returned `before` and `after`: Unreal normalizes and prunes the list, and28 stores source weights as uint16 values. The render buffer may quantize again29 to 8-bit unless the LOD enables high-precision skin weights.304. Open the rebuilt mesh with `editor(action="open_asset", assetPath=<mesh>)`31 and capture the asset editor at the reference pose and useful preview poses.32 Re-read the same selected vertices before moving on.3334The weight setter edits one existing source LOD and profile, saves only when a35selected value changed, and leaves all unlisted vertices, LODs, and profiles36alone. It does not infer bones, fit a mesh, or auto-rig a character.3738## Required loop39401. Call `project(action="get_status")`; verify the intended project and editor.412. Establish the character's authoring baseline before editing clips. Search42 for a Control Rig already bound to the target mesh/skeleton and inspect it43 with `read_control_rig_hierarchy` and `read_control_rig_graph`. It must have44 the controls, Forward Solve, and Backward Solve required for the intended45 edits. If the project or character has no suitable rig, create one first46 with the bundled Epic 5.8 controlrig actions (`epic_create`,47 `epic_import_bones_from_asset`, `epic_add_control`, deliberate Forward Solve48 nodes/links, and `epic_add_backward_solve_graph`), then save the exact rig49 with `asset(epic_save_assets)`. `epic_create` alone creates no imported50 bones, authored controls, or solver wiring. Run an unchanged51 source-to-controls-to-bones round trip on the exact production mesh. Do not52 begin production work on an unverified or merely name-compatible rig.533. Resolve the source AnimSequence, mesh, skeleton, verified Control Rig, and54 frame rate.55 When IK/retarget assets are part of the job, use `read_ik_rig` and56 `read_ik_retargeter` first. On UE 5.8 use `configure_ik_rig` for validated57 roots, ancestry-valid chains, concrete goals, solver connections and58 effectors; use `configure_ik_retargeter` for the default op stack, source and59 target rig assignment to every op, auto/manual mappings, preview meshes, and60 a named retarget pose. Read both assets back after saving. A chain's goal61 string is not proof that a goal or solver exists.624. Create a versioned session with `begin_control_rig_edit`. Use a unique63 LevelSequence path and `bindingTag`, an end-exclusive frame range, and64 `onConflict="error"`. Use `rigMode="asset"` for a project rig or `"fk"` only65 when generated FK controls are intentional. The source must be non-additive66 and mesh-compatible; flatten an additive clip against its intended base67 first. `layered` controls the session layer, not an additive source base.68 A finite non-zero source `RateScale` is compensated in Sequencer so the raw69 timeline maps once without modifying the source asset; zero is rejected.705. Call `read_control_rig_edit` at rest, transitions, extrema, and end in both71 `local` and `global` space. Here `global` is rig/global (normally mesh72 component) space, not actor world space.736. Inspect every control's `controlType`, `animatable`, and enum metadata. Write74 scalars with the matching `set_bool`, `set_float`, or `set_int`; enum values75 must come from `enumOptions`. Never write `animatable=false` controls.767. Define anatomical component-space targets, then solve proximal to distal:77 shoulder/upper arm, elbow pole and bend, forearm direction, wrist, palm78 normal, then secondary motion. For a wave, the forearm must rise, the wrist79 must sit above the elbow/near the shoulder region, and the probed palm normal80 must face the intended viewer before wrist oscillation is added.818. When an axis is uncertain, make an immutable probe session. Apply a small82 positive and negative rotation to one local axis at one fixed frame, bake,83 and inspect the resulting component-space shoulder/forearm/hand landmarks84 with `analyze_animation`. Probe the right side separately; mirrored parents85 or negative scale can reverse anatomical meanings. Preserve the full scale86 read from the control.879. Apply absolute `set_keys` transforms with finite normalized quaternions,88 complete translation/rotationQuaternion/scale payloads, and strictly89 increasing frames. Preserve translation and scale unless intentionally90 editing them. If the source bake has dense keys, key every affected frame;91 sparse keys will not replace the intervening source motion. Apply related92 controls and scalar switches in one transaction.93 For a fixed contact, use `contact_lock` in the same operation batch. Supply a94 keyable translatable driver, optional driven bone/socket, inclusive frame95 range, component-space target, optional pole/stabilizer controls, and96 position/rotation tolerances. The session must contain one source animation97 section. The bridge samples it per frame, writes dense smooth-edged keys, and98 transactionally reads back the driver and stabilizers. A driven bone/socket99 returns `verification=bake_and_analyze_required`; bake, analyze every100 constrained frame, and reject the output if its residual misses the motion's101 acceptance tolerance. To follow a moving source bone/socket, set102 `targetReference`; omit `target` to preserve the first-frame relative103 transform, or provide `target` as an explicit transform in the reference's104 space. This is the generic two-hand/hand-to-prop relationship primitive. FK105 contacts whose translation is ignored by skeleton106 retargeting use a local rotation-chain solve and report107 `solver=fk_rotation_chain`; that path requires a driven bone and does not108 accept stabilizers. Position-only locks leave the driven control orientation109 unkeyed. The bridge does not guess the driver, pole, foot roll, friction,110 joint limits, or pelvis compensation.11110. Read back the edited frames in local and global space. Reject elbow flips,112 discontinuities, wrong forearm direction, wrong palm normal, or unexpected113 changes outside the edited chain before baking.11411. Bake to a new versioned AnimSequence with `bake_control_rig_edit`,115 `reduceKeys=false`, and `onConflict="error"`. Never overwrite source,116 another iteration's session, or prior approved output assets.117118## Validation and visual review119120Run `analyze_animation` on source and output using the same mesh, explicit121frames, and bones. Include root, pelvis, the complete edited chain, feet,122opposite side, and any controls/bones expected to remain unchanged. Write its123native `manifest.json` and `samples.ndjson` beneath124`Saved/Codex/AnimationQA`.125126Check numeric integrity, invalid transforms, selected-bone bounds, root127displacement/speed, and loop seam metrics. Derive gesture-specific checks from128component transforms: shoulder-relative wrist height, elbow-to-wrist vector,129elbow angle/plane stability, probed palm-normal alignment, speed/acceleration,130direction changes, and drift in untouched bones. Numeric samples are the source131of truth; screenshots are the human visual gate.132133Use the analyzer's `rateScale`, `effectiveDurationSeconds`, and per-notify134`rawTriggerTimeSeconds` / `effectiveTriggerTimeSeconds` fields when validating135gameplay release timing. Effective times use the asset-rate magnitude and are136null when the asset rate is zero.137138For an exact native frame capture, without Computer Use or Python:1391401. `editor(action="open_asset", assetPath=<baked_anim>)`.1412. `editor(action="find_object")` for `className="AnimSingleNodeInstance"`,142 `nameContains="AnimPreviewInstance"`, `world="any"`; select the match under143 the current `AnimationEditorPreviewActor`.1443. In one `editor(action="invoke_object_functions")` call, invoke `SetPlaying` with145 `bIsPlaying=false`, then `SetPosition` with146 `InPosition=frame*rateDenominator/rateNumerator` and147 `bFireNotifies=false` on that object path.1484. Open the asset again to focus its window and call149 `editor(action="capture_screenshot", target="window")`.1505. Capture start, entry, both extrema, exit, and end with a consistent view.151152Keep versioned V&V fixtures for a from-scratch gesture, full-body IK authoring,153a retarget between known skeletons, a copied animation modified through IK plus154its pole target, a bone/socket contact with an unrelated simultaneous edit, and155edge cases covering mirrored/negative scale, dense keys, additive-source156rejection/flattening, layered sessions, scalar enums, root motion, loops, and157short clips.158159The loop generalizes beyond humanoid arms. Re-discover the rig mapping, then160express legs as hip/knee-pole/foot/contact constraints; spine and head as161arc/twist/aim constraints; tails, tentacles, and ropes as length-preserving162chain curves with delayed phase; and props or mechanisms as pivot, attachment,163contact, and clearance constraints. Only control/bone names, axes/signs,164mirrored scale, limits, and motion constraints are rig-specific.165166## Compatibility and endpoint rule167168The four Control Rig session actions, `configure_ik_rig`,169`configure_ik_retargeter`, and `contact_lock` are UE 5.8 only and return170`unsupported_engine_version` on older engines; do not invent a reflected or171raw-bone fallback. Legacy IK create/read behavior is unchanged.172`analyze_animation` is cross-version through the native APIs in the compiled173engine. See the public174[Native Control Rig Animation](https://ue-mcp.com/docs/control-rig-animation/)175guide for full call shapes and fixture guidance.176177Edit ranges are `[startFrame, endFrameExclusive)`. The bridge keeps an internal178support frame for Unreal's exact-duration export sample without making the179exclusive end authorable. Validate the last visible frame and exact-duration180sample separately. A non-looping endpoint must hold the intended final pose181without an adjacent-frame teleport or rotation jump; a looping endpoint must182pass the requested seam check. A large endpoint discontinuity fails the bake.