| name | animsequence |
| display_name | Animation Sequences & Editing |
| description | Create and edit AnimSequence keyframes and tracks — add/remove keyframes, set bone tracks, query sequence info, and bake edits (AnimSequenceService). Use when the user asks to create a new animation sequence, add keyframes/tracks, or edit raw animation data. For constraint-aware bone posing, also load animation-editing. |
| vibeue_classes | ["AnimSequenceService","SkeletonService"] |
| unreal_classes | ["AnimSequence","Skeleton","SkeletalMesh"] |
| keywords | ["animation","sequence","keyframe","curve","notify","sync marker","root motion","pose","bone track","animation editing","bone rotation","bone space","local space","component space","constraint","joint limit","preview","validate","bake","retarget","skeleton profile","learned constraints","mirror","copy pose","create animation","swing","wave","dance","jump","walk","run","attack","axe swing","arm raise"] |
🧠 Brains complement: IF an unreal-engine-skills-manager tool (external MCP) exists in this session, call it with {action: "load", skill: "animation-system"} for UE domain knowledge on this topic — correct APIs, architecture, best practices — and treat it as the rubric for any review / "best practices" question. If no such tool is available (e.g. running under Claude Code or Codex without that MCP), skip this line entirely and proceed with this skill alone — do NOT attempt the call.
Animation Sequence & Editing Skill
This skill covers the inspect → profile → preview → validate → bake workflow for safe animation bone edits with correct bone-space handling and constraint validation.
Loading skills: skills load via the engine's AgentSkillToolset (ListSkills / GetSkills) —
there is no vibeue-skills-manager tool. Run the VibeUE services below with execute_python_code
(unreal.AnimSequenceService.<method>() / unreal.SkeletonService.<method>()).
Related Skills:
- skeleton - For modifying skeleton bone transforms/hierarchy and retargeting modes
- animation-blueprint - For state machines and AnimGraph navigation
Workflow: Create skeleton profile → Learn constraints → Preview bone rotations → Validate pose → Bake to keyframes
🛡️ SAFE DISCOVERY: Always use VibeUE service methods
DO NOT use unreal.load_asset() in loops - causes memory crashes!
USE THESE SAFE METHODS:
unreal.SkeletonService.list_skeletons(search_path) - Find skeletons
unreal.AnimSequenceService.find_animations_for_skeleton(skeleton_path) - Find animations
unreal.AnimSequenceService.list_anim_sequences(search_path, skeleton_filter) - List all animations
These methods query asset metadata WITHOUT loading assets into memory.
- animation-blueprint - For state machines and AnimGraph navigation
Workflow: Create skeleton profile → Learn constraints → Preview bone rotations → Validate pose → Bake to keyframes
⚠️ Critical Rules
1. Always Specify Bone Space
All bone rotations must specify the coordinate space. Default to "local" for user intent.
| Space | Description | Use For |
|---|
"local" | Relative to parent bone | Most edits (default) |
"component" | Relative to skeletal mesh root | Cross-bone coordination |
"world" | World coordinates | Rarely used for animations |
unreal.AnimSequenceService.apply_bone_rotation(path, "arm", rot, ...)
unreal.AnimSequenceService.preview_bone_rotation(
path, "upperarm_r", unreal.Rotator(0, 30, 0), "local", 0
)
2. Use Preview → Validate → Bake Workflow
Never apply edits directly without validation. Use the preview workflow:
import unreal
anim_path = "/Game/Anims/AS_Idle"
result = unreal.AnimSequenceService.preview_bone_rotation(
anim_path, "upperarm_r", unreal.Rotator(0, 45, 0), "local", 0
)
validation = unreal.AnimSequenceService.validate_pose(anim_path, True)
if not validation.is_valid:
for msg in validation.violation_messages:
print(f"⚠️ {msg}")
unreal.AnimSequenceService.cancel_preview(anim_path)
if validation.is_valid:
result = unreal.AnimSequenceService.bake_preview_to_keyframes(
anim_path, 0, -1, "cubic"
)
print(f"✓ Baked frames {result.start_frame} to {result.end_frame}")
3. Build Skeleton Profile Before Editing
Create a skeleton profile to get hierarchy, constraints, and learned ranges:
unreal.AnimSequenceService.apply_bone_rotation(...)
profile = unreal.SkeletonService.create_skeleton_profile("/Game/SK_Mannequin")
print(f"Skeleton has {profile.bone_count} bones")
if not profile.has_learned_constraints:
constraints = unreal.SkeletonService.learn_from_animations("/Game/SK_Mannequin", 50, 10)
print(f"Learned from {constraints.animation_count} animations")
4. Use Quaternions Internally, Euler for Intent
User intent is expressed in Euler angles (degrees), but always use quaternions internally to avoid gimbal lock:
rotation_delta = unreal.Rotator(0, 30, 0)
result = unreal.AnimSequenceService.preview_bone_rotation(
anim_path, "lowerarm_r", rotation_delta, "local", 0
)
euler = unreal.AnimSequenceService.quat_to_euler(some_quat)
COMMON_MISTAKES
Wrong: Applying rotations without space
transform = unreal.Transform(rotation=some_rotation)
result = unreal.AnimSequenceService.preview_bone_rotation(
anim_path, bone, rotation, "local", frame
)
Wrong: Editing without validation
unreal.AnimSequenceService.apply_bone_rotation(
path, "lowerarm_r", unreal.Rotator(0, 180, 0),
"local", 0, -1, True
)
result = unreal.AnimSequenceService.preview_bone_rotation(...)
validation = unreal.AnimSequenceService.validate_pose(path, True)
if validation.is_valid:
unreal.AnimSequenceService.bake_preview_to_keyframes(...)
Wrong: Guessing bone axis orientations
rotation = unreal.Rotator(0, 90, 0)
ref_pose = unreal.AnimSequenceService.get_reference_pose(skeleton_path)
for bp in ref_pose:
if bp.bone_name == "upperarm_r":
euler = unreal.AnimSequenceService.quat_to_euler(bp.transform.rotation)
print(f"Reference: Roll={euler.roll}, Pitch={euler.pitch}, Yaw={euler.yaw}")
Wrong: Not building skeleton profile
unreal.AnimSequenceService.preview_bone_rotation(...)
unreal.SkeletonService.create_skeleton_profile(skeleton_path)
⚠️ CRITICAL: Loading assets in loops causes crashes
asset_subsystem = unreal.get_editor_subsystem(unreal.EditorAssetSubsystem)
assets = asset_subsystem.list_assets("/Game", recursive=True)
for asset_path in assets:
anim = unreal.load_asset(asset_path)
if anim and hasattr(anim, 'get_skeleton'):
skeleton = anim.get_skeleton()
asset_registry = unreal.AssetRegistryHelpers.get_asset_registry()
filter = unreal.ARFilter(
class_paths=[unreal.TopLevelAssetPath("/Script/Engine", "AnimSequence")],
recursive_paths=True,
package_paths=["/Game"]
)
anim_assets = asset_registry.get_assets(filter)
for asset_data in anim_assets:
anim_name = asset_data.asset_name
anim_path = asset_data.object_path
skeleton_tag = asset_data.get_tag_value("Skeleton")
Why this crashes:
unreal.load_asset() loads full asset into memory
- Loading hundreds of animations in a loop exhausts memory
- Unreal's garbage collection can't keep up
- Results in exception code 0xC0000005 (access violation)
Safe alternatives:
- USE VibeUE's
FindAnimationsForSkeleton() - BEST OPTION
- Use Asset Registry API to query metadata without loading
- Load one asset at a time with explicit unload
- Filter by path before loading (limit scope)
BEST: Use VibeUE AnimSequenceService methods
import unreal
skeleton_path = "/Game/Characters/SK_Mannequin"
anims = unreal.AnimSequenceService.find_animations_for_skeleton(skeleton_path)
for anim_info in anims[:10]:
print(f"{anim_info.anim_name}")
print(f" Duration: {anim_info.duration:.2f}s")
print(f" Frames: {anim_info.frame_count}")
print(f" Path: {anim_info.anim_path}")
Other safe VibeUE methods:
list_anim_sequences(search_path, skeleton_filter) - List all in path
get_anim_sequence_info(anim_path) - Get single anim info
search_animations(name_pattern, search_path) - Find by name pattern
IMPORTANT: Asset Path Format
All anim_path parameters require the FULL asset path (package_name), NOT the folder path (package_path).
When using AssetDiscoveryService.search_assets(), use package_name NOT package_path:
import unreal
results = unreal.AssetDiscoveryService.search_assets("Run", "AnimSequence")
if results:
asset = results[0]
anim_path = str(asset.package_name)
info = unreal.AnimSequenceService.get_anim_sequence_info(anim_path)
Sub-docs available
Load these sibling docs for deeper coverage of specific topics:
- api-reference.md - Full Python API reference (SkeletonService profile/constraint methods, AnimSequenceService preview/edit/pose/visual capture, creation/helper/query methods, key structs). Also contains the secondary skill manifest for the merged "Animation Sequence Skill" content set.
- data-structures.md - Key data structures (FSkeletonProfile, FBoneConstraint, FLearnedBoneRange, FAnimationEditResult, FAnimationPoseCaptureResult, FBoneDelta) and full DTO reference (AnimSequenceInfo, BoneTrackData, AnimKeyframe, BonePose, AnimCurveInfo, CurveKeyframe, AnimNotifyInfo, SyncMarkerInfo).
- workflows.md - Editing workflows (inspect, preview/validate single bone, multi-bone atomic, manual constraints, learn from animations, copy/mirror pose, retarget preview) and creation workflows (from reference pose, from keyframe data, simple keyframes, rotation keyframes, wave animation example).
- patterns.md - Common patterns (listing animations, getting pose at time, adding curves, managing/configuring notifies) and the CRITICAL RULES checklist for creation/notify operations and asset paths.
- method-categories.md - Categorised table of every AnimSequenceService method by domain (Discovery, Creation, Helpers, Properties, Bone Tracks, Poses, Curves, Notifies, Notify Tracks, Sync Markers, Root Motion, Additive, Compression, Export, Editor).
- bone-rotation.md - Bone Rotation Axis Discovery: why bone local coordinate systems are non-intuitive and the required discovery workflow (reference pose values → analyze existing animations → incremental axis testing) before writing rotation animation code.
Sample scripts (run via execute_python_code)
scripts/inspect_sequence.txt — safely inspect AnimSequences for a skeleton (metadata, no asset loading).