Keyframe animation, rigging, constraints, and armatures in Blender. Use for animation, rigging, camera movement, or when user mentions "animate," "keyframe," "rig," or "armature."
Scanned 9/3/2026
Install to Claude Code
npx -y skills add sideshowroberto/vfx-agent-toolkit --skill blender-animation --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Blender Animation?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/sideshowroberto-blender-animation)More formats (shields.io, HTML) on the badges page.
---
name: blender-animation
description: Keyframe animation, rigging, constraints, and armatures in Blender. Use for animation, rigging, camera movement, or when user mentions "animate," "keyframe," "rig," or "armature."
allowed-tools: Read,Write
---
# Blender Animation Skill
**Version:** 2.0.0
**Last Updated:** 2026-06-10
**Dependencies:** Blender 5.1+
---
## Animation System Status (5.1+)
**All core animation APIs are stable - no breaking changes from 4.x to 5.1.**
Validated: `obj.keyframe_insert()`, F-curve access, armature creation, constraints, shape keys, drivers, NLA system.
---
## QUICK START
### Basic Object Animation
```python
import bpy
# Create cube via direct API
mesh = bpy.data.meshes.new("AnimatedMesh")
vertices = [
(-1,-1,-1), (1,-1,-1), (1,1,-1), (-1,1,-1),
(-1,-1,1), (1,-1,1), (1,1,1), (-1,1,1)
]
faces = [
[0,1,2,3], [4,5,6,7], [0,1,5,4],
[2,3,7,6], [0,3,7,4], [1,2,6,5]
]
mesh.from_pydata(vertices, [], faces)
obj = bpy.data.objects.new("AnimatedCube", mesh)
bpy.context.collection.objects.link(obj)
# Animate location
scene = bpy.context.scene
scene.frame_set(1)
obj.location = (0, 0, 0)
obj.keyframe_insert(data_path="location", frame=1)
scene.frame_set(50)
obj.location = (5, 0, 0)
obj.keyframe_insert(data_path="location", frame=50)
scene.frame_set(100)
obj.location = (5, 5, 0)
obj.keyframe_insert(data_path="location", frame=100)
print(f"Created animation with {len(obj.animation_data.action.fcurves)} F-curves")
```
---
## STANDARD WORKFLOWS
### Workflow 1: Camera Animation with Constraints
**Use When:** Creating animated camera for cinematics or previews
```python
import bpy
camera_data = bpy.data.cameras.new("AnimatedCamera")
camera_obj = bpy.data.objects.new("Camera", camera_data)
bpy.context.collection.objects.link(camera_obj)
# Create target object
target_obj = bpy.data.objects.get("TargetObject") # Must exist
# Add Track-To constraint
track_constraint = camera_obj.constraints.new(type='TRACK_TO')
track_constraint.target = target_obj
track_constraint.track_axis = 'TRACK_NEGATIVE_Z'
track_constraint.up_axis = 'UP_Y'
# Animate camera position
scene = bpy.context.scene
scene.frame_set(1)
camera_obj.location = (10, -10, 5)
camera_obj.keyframe_insert(data_path="location", frame=1)
scene.frame_set(50)
camera_obj.location = (0, -15, 8)
camera_obj.keyframe_insert(data_path="location", frame=50)
scene.frame_set(100)
camera_obj.location = (-10, -10, 5)
camera_obj.keyframe_insert(data_path="location", frame=100)
```
---
### Workflow 2: Character Armature Rigging
**Use When:** Setting up character animation with IK/FK controls
```python
import bpy
armature_data = bpy.data.armatures.new("CharacterRig")
armature_obj = bpy.data.objects.new("Armature", armature_data)
bpy.context.collection.objects.link(armature_obj)
# NOTE: Bone creation in edit mode is easiest in Blender UI.
# For scripted bone creation, set active + switch mode:
bpy.context.view_layer.objects.active = armature_obj
bpy.ops.object.mode_set(mode='EDIT')
edit_bones = armature_data.edit_bones
hip = edit_bones.new("Hip")
hip.head = (0, 0, 0)
hip.tail = (0, 0, 1)
spine = edit_bones.new("Spine")
spine.head = (0, 0, 1)
spine.tail = (0, 0, 2)
spine.parent = hip
bpy.ops.object.mode_set(mode='OBJECT')
# Add IK constraint in pose mode
bpy.ops.object.mode_set(mode='POSE')
pose_bone = armature_obj.pose.bones.get("Spine")
if pose_bone:
ik = pose_bone.constraints.new(type='IK')
ik.chain_count = 2
bpy.ops.object.mode_set(mode='OBJECT')
```
---
### Workflow 3: Shape Key Animation (Facial Expressions)
**Use When:** Animating mesh morphs for facial expressions or deformations
```python
import bpy
mesh_obj = bpy.data.objects.get("CharacterHead") # Must exist
# Add basis shape key
basis = mesh_obj.shape_key_add(name="Basis")
# Add expression shape keys
smile = mesh_obj.shape_key_add(name="Smile")
blink = mesh_obj.shape_key_add(name="Blink")
# Animate shape key values
scene = bpy.context.scene
scene.frame_set(1)
smile.value = 0.0
smile.keyframe_insert(data_path="value", frame=1)
scene.frame_set(12)
smile.value = 1.0
smile.keyframe_insert(data_path="value", frame=12)
scene.frame_set(24)
smile.value = 0.0
smile.keyframe_insert(data_path="value", frame=24)
```
---
## API REFERENCE
### Keyframe Operations
```python
import bpy
# Insert keyframe
obj.keyframe_insert(data_path="location", frame=10, index=-1)
# data_path: "location", "rotation_euler", "scale", etc.
# index: -1 for all axes, 0/1/2 for X/Y/Z
# Delete keyframe
obj.keyframe_delete(data_path="location", frame=10, index=-1)
# Create animation data manually
anim_data = obj.animation_data_create()
```
### F-Curve Access
```python
import bpy
# Safe access pattern
if obj.animation_data and obj.animation_data.action:
fcurves = obj.animation_data.action.fcurves
for fc in fcurves:
print(f"{fc.data_path}[{fc.array_index}]: {len(fc.keyframe_points)} keyframes")
# Insert keyframe point directly
fcurve = obj.animation_data.action.fcurves[0]
point = fcurve.keyframe_points.insert(frame=25, value=2.5)
point.interpolation = 'BEZIER' # or 'LINEAR', 'CONSTANT'
```
### Constraints
```python
import bpy
# IK constraint
pose_bone = armature_obj.pose.bones["BoneName"]
ik = pose_bone.constraints.new(type='IK')
ik.target = target_obj
ik.subtarget = "TargetBone"
ik.chain_count = 2
# Copy Location
copy_loc = pose_bone.constraints.new(type='COPY_LOCATION')
copy_loc.target = target_obj
```
---
## TROUBLESHOOTING
### Keyframe Not Inserted
```python
import bpy
# Verify property path exists
if hasattr(obj, "location"):
result = obj.keyframe_insert(data_path="location", frame=1)
print(f"Keyframe inserted: {result}")
# Check animation data was created
if obj.animation_data and obj.animation_data.action:
print(f"F-curves: {len(obj.animation_data.action.fcurves)}")
else:
print("No animation data - keyframe_insert may have failed")
```
### Constraint Not Working
```python
import bpy
# Verify target exists
target_obj = bpy.data.objects.get("TargetObject")
if not target_obj:
print("Error: Target object not found")
else:
constraint = pose_bone.constraints.new(type='IK')
constraint.target = target_obj
# Verify subtarget bone
if "TargetBone" in target_obj.pose.bones:
constraint.subtarget = "TargetBone"
# Check constraints are active
for c in pose_bone.constraints:
print(f"{c.name}: muted={c.mute}")
```
---
## VALIDATION CHECKLIST
- [ ] Animation data exists (`obj.animation_data is not None`)
- [ ] F-curves created (`len(action.fcurves) > 0`)
- [ ] Frame range set (`scene.frame_start`, `frame_end`)
- [ ] Keyframes at expected frames
- [ ] Constraints have valid targets
- [ ] Timeline playback works
---
## VERSION HISTORY
**v2.0.0** (2026-06-10) - MCP migration
- Removed HTTP Bridge connection steps and curl health-check
- Removed `import requests` / `requests.post()` wrappers
- Added `import bpy` to all code blocks
- Updated target: Blender 5.1+
- Workflow 2 now shows full operator-based bone creation (valid with MCP context)
**v1.0.0** (2025-10-24) - Initial release
---
**Status:** Production Ready
**Maintainer:** VFX Pipeline Team
**Dependencies:** Blender 5.1+
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!