← LeaderboardThe Skill Leaderboard

blender-animation

Animation in Blender 5.2 - slotted/layered actions and the channelbag API, Python keyframing, F-curves, game loops with pop/hitch checks, NLA clips, pose library, mocap/BVH/Mixamo retargeting with auto bone maps, baking control rigs to export skeletons, root motion, per-clip export. Use for any keyframe, action, NLA, mocap, or animation-export task.

Published by EL4CTEO ↗EL4CTEO/blender-skills

Try your first task

A source-grounded starter task has not been verified for this skill yet.

SKILL.md

name: blender-animationdescription: Animation in Blender 5.2 - slotted/layered actions and the channelbag API, Python keyframing, F-curves, game loops with pop/hitch checks, NLA clips, pose library, mocap/BVH/Mixamo retargeting with auto bone maps, baking control rigs to export skeletons, root motion, per-clip export. Use for any keyframe, action, NLA, mocap, or animation-export task.license: MITmetadata:   author: blender-agent-skills  version: "1.2.0"

Animation

The execution model is in blender-core (its references/bpy-patterns.md has verified keyframe/driver snippets). Rigs are in blender-character-rigging.

5.x data model (what changed)

  • An Action holds slots (one per animated ID) and layers → strips → channelbags → F-curves. A single action can animate several objects (e.g. a rig and its camera) through different slots.
  • Assign: ob.animation_data.action = act, then make sure ob.animation_data.action_slot is set (picked automatically when a suitable slot exists; otherwise act.slots.new(id_type="OBJECT", name=ob.name)).
  • F-curves: cb = anim_utils.action_ensure_channelbag_for_slot(act, slot), then cb.fcurves.ensure(path, index=i, group_name=...). action.fcurves no longer exists.
  • The simplest route is still pb.keyframe_insert("rotation_quaternion", frame=f), which creates the action, slot and channelbag.

Workflow (keyframe animation, studio style)

  1. Blocking: key poses on every channel (CONSTANT interpolation, bpy.context.preferences.edit.keyframe_new_interpolation_type) on golden frames (contact, down, passing, up for walks).
  2. Breakdowns: add in-betweens that define arcs and spacing.
  3. Spline: switch to BEZIER, fix spacing in the Graph Editor, and clean overshoot. Auto-clamped handles avoid overshoot.
  4. Polish: offsets/overlap (follow-through on hair, tails, cloth bones), arcs, moving holds (never a perfectly frozen character), and contact stability (feet locked with IK).
  5. Review: MCP look(mode="frames", frame_count=8) or a Workbench playblast (blender-rendering).

Game animation rules

  • One action per clip, named <Rig>_<Clip> or just <Clip>, with a fake user so it survives saving.
  • Loops: first and last frames identical. Export frames 1..N and let the engine drop the duplicate, or exclude the last frame (UE/Unity "loop pose" options). An F-curve CYCLES modifier helps preview but doesn't export, so bake it. Verify with scripts/loop_check.py -- --object RIG --action Walk [--root-motion root] [--fix]: it reports pose pops (last ≠ first, per bone, in deg/m) and speed hitches across the seam, and --fix keys the first-frame values on the last frame (root travel is kept).
  • FPS: author at 30 (or 24) and let engines resample. Set scene.render.fps before importing mocap.
  • Root motion: the root bone carries the translation (and yaw). The hips keep the bob/sway. scripts/bake_action.py --root-motion xy moves the hips' ground motion to the root. In-place clips: the root stays at the origin.
  • Additive/overlay clips (aim offsets, breathing) are exported as normal clips and marked additive in the engine.
  • Keep the bone transform channels the engine expects. Don't animate bone scale unless the engine supports it (Roblox and many mobile pipelines don't).

Bake control rig → export skeleton

scripts/bake_action.py -- --list
scripts/bake_action.py -- --source RIG_Body --target GAME_RIG_Body [--actions Walk Run] [--root-motion xy --hips spine]

This gives one baked action per clip (GAME_RIG_Body|Walk), cleaned, with fake users, plus one muted NLA track per clip (CLIP_Walk) so FBX (bake_anim_use_nla_strips/all actions) and glTF (ACTIONS mode) export every clip. The target's constraints are muted afterward so it plays the baked data; run --follow to drive it live again. Self-bake (IK/constraints → keys on the same rig): --source X --target X.

Mocap and retargeting

  • Import: bpy.ops.import_anim.bvh(filepath=..., global_scale=0.01 if cm else 1, rotate_mode="NATIVE", update_scene_fps=True), import_scene.fbx (Mixamo, automatic_bone_orientation=True).
  • Retarget: scripts/retarget.py -- --source Mocap --target GAME_RIG [--map auto|map.json] [--in-place] [--name Walk]. Each target bone gets the source bone's world rotation change from rest on its own rest orientation, so rolls, bone axes, Y-up/cm FBX object transforms and proportions don't matter. The hips travel is scaled by the hips-height ratio. Keys go straight into a new TARGET|Name action (quaternion, linear, fake user). Measured on a Mixamo-style rig (Y-up, 0.01 scale, rolled) → Rigify-named rig with 15% longer legs: 17 bones, < 0.1° error.
  • The auto map understands Mixamo (mixamorig:LeftUpLeg), Rigify DEF-/ORG-, UE/Unity/BVH-style names, and spine chains of different lengths. Check it first with --show-map (unmapped_key_parts must be empty), and pass a JSON {target: source} for anything custom (fingers, props).
  • Rest poses must match (T vs A matters most): pose the target's rest like the source's first. Then clean, add root motion, and export with bake_action.py.
  • Clean mocap: decimate keys (graph.decimate, ratio 0.3–0.5), use an F-curve SMOOTH modifier or the Butterworth filter (graph.butterworth_smooth), and fix foot sliding with IK pins and then bake.
  • Production retarget tools: Auto-Rig Pro (paid), Rokoko (free), and the engine-side retargeters (UE IK Retargeter, Unity Humanoid).

NLA and pose library

  • NLA: push actions down as strips (track.strips.new(name, start, action)) to layer/blend clips (blend type REPLACE/ADD/COMBINE), and use Tweak mode to edit. Strips need an action slot set when the action has several slots (strip.action_slot).
  • The pose library (bundled pose_library) stores poses as assets: poselib.create_pose_asset(pose_name=...), poselib.apply_pose_asset / blend_pose_asset. Use it for hand shapes, face poses, and a T/A rest pose.

Shape keys and other properties

Any property can be keyed: kb.keyframe_insert("value", frame=f) (shape key), mat.node_tree.nodes[...].inputs[...].keyframe_insert("default_value") (materials, which engines usually ignore), custom props ob.keyframe_insert('["prop"]').

Gotchas

  • pb.matrix = ... followed by keyframe_insert needs the right scene.frame_set(f) first, or an evaluation overwrites the pose.
  • Connected bones (use_connect) can't translate. Hips/pelvis must be unconnected from the root.
  • bake_action with visual keying reads evaluated poses, so constraints, IK and drivers are all captured. Mute the target's own constraints afterward (the script does), or they keep overriding the keys.
  • Quaternion vs Euler: game bones should use QUATERNION (no gimbal lock, smooth slerp). Euler is fine for single-axis controls. Don't mix modes between keys.
  • glTF sampling: export_force_sampling bakes every frame (the safe default). Non-linear F-curve modifiers and drivers only export when sampled.