Ue Animation System logo

Ue Animation System

Community
kevinpbuckley
ue-animation-system

Animate skeletal meshes in Unreal using the AnimInstance / Animation Blueprint model — C++ UAnimInstance base class (NativeInitializeAnimation, NativeUpdateAnimation, NativeThreadSafeUpdateAnimation), AnimGraph with state machines and blend spaces, animation assets (UAnimSequence, UBlendSpace, UAnimMontage, UAnimComposite, UPoseAsset), anim notifies and notify states, montage playback and delegates, linked anim layers, Motion Matching (Pose Search plugin), and Motion Warping. Use when setting up character animation, driving locomotion blends from C++, playing montages for actions, firing gameplay events at precise animation frames (notifies), switching animation sets at runtime, or integrating the Pose Search / Motion Warping plugins.

Overview

Publisherkevinpbuckley
Repositoryunreal-engine-skills
Skill nameue-animation-system
Stars
89
Forks
9
Bundled files
4
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 4 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by kevinpbuckley on GitHub. Read the source before you install it.

Installation

Install the Ue Animation System AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/kevinpbuckley/unreal-engine-skills/tree/master/skills/core/ue-animation-system
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/kevinpbuckley/unreal-engine-skills.git /tmp/unreal-engine-skills
mkdir -p .claude/skills
cp -r /tmp/unreal-engine-skills/skills/core/ue-animation-system .claude/skills/ue-animation-system
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Ue Animation System in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Ue Animation System on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Ue Animation System is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Animation system

A USkeletalMeshComponent is animated by a UAnimInstance — the runtime behind an Animation Blueprint. The recommended architecture is a C++ UAnimInstance base that computes animation variables each frame, with the AnimBP's AnimGraph consuming those variables to produce the final pose.

When to use this skill

  • Setting up a character's locomotion (idle, walk, run, jump) with state machines and blend spaces driven from C++.
  • Playing one-off animations (attacks, reloads, hit reactions) via montages with section control and completion delegates.
  • Firing gameplay events (footsteps, hit windows, VFX triggers) at precise animation frames using custom anim notifies.
  • Switching animation sets at runtime with linked anim layers / LinkAnimClassLayers.
  • Integrating the Pose Search (Motion Matching) or Motion Warping plugins.

Core mental model

ThreadWhat runs thereWhat to do there
Game threadNativeInitializeAnimation, NativeUpdateAnimation, event graphCache references, compute simple vars
Anim worker threadNativeThreadSafeUpdateAnimation, AnimGraph evaluationHeavy per-frame logic (read-only, no world queries)

The AnimGraph evaluates the pose (state machines → blend spaces → IK → final pose). It runs on the anim worker thread and must only read data the game thread wrote. The C++ update path computes the variables the graph reads — never drive the final bone transform directly from game code.

C++ AnimInstance base

cpp
// MyAnimInstance.h
#pragma once
#include "Animation/AnimInstance.h"
#include "MyAnimInstance.generated.h"

UCLASS()
class MYGAME_API UMyAnimInstance : public UAnimInstance
{
    GENERATED_BODY()
public:
    virtual void NativeInitializeAnimation() override;
    virtual void NativeUpdateAnimation(float DeltaSeconds) override;
    virtual void NativeThreadSafeUpdateAnimation(float DeltaSeconds) override;

    // Read by AnimGraph nodes (BlueprintReadOnly keeps them graph-accessible, thread-safe)
    UPROPERTY(BlueprintReadOnly, Category="Locomotion") float Speed = 0.f;
    UPROPERTY(BlueprintReadOnly, Category="Locomotion") float Direction = 0.f;
    UPROPERTY(BlueprintReadOnly, Category="Locomotion") bool  bIsFalling = false;

private:
    UPROPERTY() TObjectPtr<class ACharacter> OwnerCharacter;
};
cpp
// MyAnimInstance.cpp
#include "MyAnimInstance.h"
#include "GameFramework/Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "KismetAnimationLibrary.h"   // CalculateDirection

void UMyAnimInstance::NativeInitializeAnimation()
{
    Super::NativeInitializeAnimation();
    OwnerCharacter = Cast<ACharacter>(TryGetPawnOwner());  // cache once; safe on game thread
}

void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);
    // Keep lightweight — prefer NativeThreadSafeUpdateAnimation for heavy logic
    if (!OwnerCharacter) { OwnerCharacter = Cast<ACharacter>(TryGetPawnOwner()); }
}

void UMyAnimInstance::NativeThreadSafeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeThreadSafeUpdateAnimation(DeltaSeconds);
    if (!OwnerCharacter) { return; }
    const FVector Vel = OwnerCharacter->GetVelocity();
    Speed     = Vel.Size2D();
    bIsFalling = OwnerCharacter->GetCharacterMovement()->IsFalling();
    Direction = UKismetAnimationLibrary::CalculateDirection(Vel, OwnerCharacter->GetActorRotation());
}

Key rules:

  • NativeInitializeAnimation — cache owner/movement references; runs once on game thread.
  • NativeUpdateAnimation — game-thread update; keep minimal; call Super first.
  • NativeThreadSafeUpdateAnimation — worker-thread update; no UWorld queries, no spawning, no non-thread-safe engine calls. This is where to put heavy per-frame computation.
  • Assign variables used by the AnimGraph as UPROPERTY(BlueprintReadOnly) — the AnimGraph nodes read them by name. BlueprintThreadSafe meta is needed if accessed in thread-safe graph functions.

Assign at runtime:

cpp
GetMesh()->SetAnimInstanceClass(MyAnimBPClass);          // TSubclassOf<UAnimInstance>
UMyAnimInstance* AI = Cast<UMyAnimInstance>(GetMesh()->GetAnimInstance());

Animation assets

AssetClassUse
Animation SequenceUAnimSequenceSingle clip bound to a skeleton
Blend Space (2D)UBlendSpaceBlend clips by two parameters (speed × direction)
Blend Space 1DUBlendSpace1DBlend clips by one parameter (speed)
Aim OffsetUAimOffsetBlendSpaceAdditive aim-offset by pitch/yaw
MontageUAnimMontageSectioned one-off animations with slot blending
CompositeUAnimCompositeStitch sequences into one timeline
Pose AssetUPoseAssetCurve-driven morph targets / facial poses

All assets target a USkeleton — clips are shareable across meshes that use the same skeleton (or compatible skeletons; see USkeleton::CompatibleSkeletons).

State machines

State machines in the AnimGraph define locomotion or combat states. Each state holds an animation graph sub-network; transitions carry rule expressions. From C++, query state machine state via FAnimNode_StateMachine:

  • GetCurrentStateName() — FName of the active state.
  • GetStateWeight(int32 StateIndex) — blend weight of a state during transition.

Prefer driving transitions through UPROPERTY variables computed in the C++ update rather than calling native state machine APIs directly.

Montages (actions on top of locomotion)

Montages play in a named slot the AnimGraph exposes. The slot node blends the montage over the base locomotion pose — good for attacks, reloads, hit reactions:

cpp
UAnimInstance* AI = GetMesh()->GetAnimInstance();

// Play and get the length (or set ReturnValueType to MontageLength / Duration)
float Len = AI->Montage_Play(AttackMontage, 1.f);

// Jump to / stop sections
AI->Montage_JumpToSection(FName("Combo2"), AttackMontage);
AI->Montage_Stop(0.2f, AttackMontage);

// ACharacter convenience wrappers
PlayAnimMontage(AttackMontage, 1.f, FName("Intro"));
StopAnimMontage(AttackMontage);

Bind to completion to know when an action finishes:

cpp
AI->OnMontageEnded.AddDynamic(this, &AMyChar::OnMontageEnded);
// or per-instance:
FOnMontageEnded EndDelegate;
EndDelegate.BindUObject(this, &AMyChar::OnMontageEnded);
AI->Montage_SetEndDelegate(EndDelegate, AttackMontage);

See references/montages-and-slots.md for section authoring, root motion, blend settings, and Montage_PlayWithBlendSettings.

Anim Notifies (events from animation)

  • UAnimNotify — a point event (footstep SFX, spawn projectile at a bone socket).
  • UAnimNotifyState — a ranged event with NotifyBegin/NotifyTick/NotifyEnd (enable weapon collision during a swing).
cpp
UCLASS()
class MYGAME_API UAnimNotify_Footstep : public UAnimNotify
{
    GENERATED_BODY()
    virtual FString GetNotifyName_Implementation() const override { return TEXT("Footstep"); }
    virtual void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
                        const FAnimNotifyEventReference& Ref) override;
};

UCLASS()
class MYGAME_API UAnimNotifyState_WeaponTrace : public UAnimNotifyState
{
    GENERATED_BODY()
    virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
                             float TotalDuration, const FAnimNotifyEventReference& Ref) override;
    virtual void NotifyTick (USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
                             float FrameDelta, const FAnimNotifyEventReference& Ref) override;
    virtual void NotifyEnd  (USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
                             const FAnimNotifyEventReference& Ref) override;
};

Notifies are the correct way to synchronize gameplay to animation timing. Using timers as a substitute diverges at variable play rates and when animation blending delays the clip.

Linked anim layers (runtime animation set swapping)

Linked anim layers let you swap a portion of the AnimGraph at runtime — useful for weapon styles, character class variations, or costume-specific animations:

cpp
// Replace the locomotion layer at runtime
GetMesh()->LinkAnimClassLayers(URifleLocomotionLayer::StaticClass());
// Revert to the default layer defined in the AnimBP
GetMesh()->UnlinkAnimClassLayers(URifleLocomotionLayer::StaticClass());
// Retrieve the active layer instance to set variables on it
UAnimInstance* Layer = GetMesh()->GetLinkedAnimLayerInstanceByClass(URifleLocomotionLayer::StaticClass());

The linked AnimBP class must implement the same UAnimLayerInterface interface as the parent.

Modern options (5.x)

  • Motion Matching (PoseSearch plugin) — data-driven locomotion selects poses from a database matching trajectory and pose queries. Replaces hand-built state machines for complex locomotion. Enable PoseSearch in the project plugins.
  • Motion Warping (MotionWarping plugin) — warps root-motion clips to hit target positions/rotations at runtime (ledge grabs, cover transitions). Add UMotionWarpingComponent to the character; annotate montages with warp windows; call AddOrUpdateWarpTargetFromTransform before playing.
  • Control Rig in the AnimGraph — procedural bone adjustments, IK, foot planting (see ue-control-rig-and-ik).
  • Layered blend per bone (FAnimNode_LayeredBoneBlend) — blend an upper-body montage slot over a lower-body locomotion pose, or blend full-body layers with per-bone masks.
  • Inertialization (AnimNode_Inertialization) — cost-efficient smooth blending by recording velocity rather than maintaining two full pose evaluations simultaneously.
  • Animation Sharing plugin — share a single AnimInstance across multiple distant characters to reduce per-character animation cost.

Gotchas

  • Non-thread-safe calls in NativeThreadSafeUpdateAnimation — any call that touches the UWorld, spawns objects, or reads non-thread-safe data will crash under multi-threaded anim update. Cache all needed references in NativeInitializeAnimation.
  • Wrong skeleton — clips won't apply; retarget with the IK Retargeter or add the mesh's skeleton to USkeleton::CompatibleSkeletons.
  • Driving the pose from game code instead of the AnimGraph — fighting the animation system. Compute data in C++; let the graph own the pose.
  • Using timers for animation-timed events instead of notifies — desync at variable play rates and when blending delays a clip's effective start.
  • Forgetting to call Super in NativeUpdateAnimation / NativeInitializeAnimation — the engine does essential bookkeeping in the base implementation.
  • Heavy game-thread logic in NativeUpdateAnimation for many characters — move it to NativeThreadSafeUpdateAnimation to run in parallel across characters.
  • Slot with no weight in the AnimGraph — montage plays but produces no output; ensure the slot node is wired between source and output and the blend weight is > 0.
  • bUseMultiThreadedAnimationUpdate disabled on the AnimBP — disables the worker-thread path; re-enable (default on) unless you deliberately need single-threaded evaluation.

Version notes

  • TObjectPtr<T> is the modern member UPROPERTY form (UE5+); older code uses raw T*.
  • NativeThreadSafeUpdateAnimation was introduced in UE 4.15 and is stable across all UE 5.x versions.
  • LinkAnimClassLayers / UnlinkAnimClassLayers replaced the deprecated SetLayerOverlay / ClearLayerOverlay (deprecated since 4.24).
  • SetAnimInstanceClass (the USkeletalMeshComponent overriding version) deprecated K2_SetAnimInstanceClass (deprecated 4.23) and a TSubclassOf setter (deprecated 5.5).
  • The PoseSearch plugin (Motion Matching) is production-ready in UE 5.4+ and ships with the engine (no separate download). API surface stabilized significantly in 5.4.

References & source material

Engine source (UE 5.8):

  • Runtime/Engine/Classes/Animation/AnimInstance.h — UAnimInstance:358, NativeInitializeAnimation:1436, NativeUpdateAnimation:1439, NativeThreadSafeUpdateAnimation:1442, NativePostEvaluateAnimation:1444, NativeBeginPlay:1457, Montage_Play:626, Montage_Stop:639, Montage_JumpToSection:663, GetCurrentActiveMontage:754, OnMontageBlendingOut:758, OnMontageEnded:770, Montage_SetEndDelegate:784, TryGetPawnOwner:465, GetOwningActor:546, GetOwningComponent:550, LinkAnimClassLayers:877, UnlinkAnimClassLayers:888, GetLinkedAnimLayerInstanceByClass:910, bUseMultiThreadedAnimationUpdate:382.
  • Runtime/Engine/Classes/Animation/AnimMontage.h — UAnimMontage:635, FCompositeSection:37, FSlotAnimationTrack:83, BlendIn:650, BlendOut:659, CompositeSections:697, SlotAnimTracks:701.
  • Runtime/Engine/Classes/Animation/AnimSequenceBase.h — UAnimSequenceBase:36, Notifies:43, RateScale:61, GetDataModel:243.
  • Runtime/Engine/Classes/Animation/AnimSequence.h — UAnimSequence:202, bEnableRootMotion:320, RootMotionRootLock:324.
  • Runtime/Engine/Classes/Animation/BlendSpace.h — UBlendSpace:470, BlendParameters:926, NotifyTriggerMode:864.
  • Runtime/Engine/Classes/Animation/BlendSpace1D.h — UBlendSpace1D:19.
  • Runtime/Engine/Classes/Animation/AnimNotifies/AnimNotify.h — UAnimNotify:51, Notify:85, GetNotifyName:59.
  • Runtime/Engine/Classes/Animation/AnimNotifies/AnimNotifyState.h — UAnimNotifyState:34, NotifyBegin:74, NotifyTick:75, NotifyEnd:76.
  • Runtime/Engine/Classes/Animation/AnimNode_StateMachine.h — FAnimNode_StateMachine:119, GetCurrentStateName:175, GetStateWeight:255.
  • Runtime/Engine/Classes/Animation/Skeleton.h — USkeleton:294, CompatibleSkeletons:345, IsCompatibleMesh:766.
  • Runtime/Engine/Classes/Components/SkeletalMeshComponent.h — SetAnimInstanceClass:1096, GetAnimInstance:1111, LinkAnimClassLayers:1194, UnlinkAnimClassLayers:1205, GetLinkedAnimLayerInstanceByClass (via UAnimInstance).
  • Runtime/Engine/Classes/GameFramework/Character.h — PlayAnimMontage:890, StopAnimMontage:894, GetCurrentMontage:898.
  • Runtime/Engine/Public/Animation/AnimNotifyQueue.h — FAnimNotifyEventReference:21.
  • Runtime/AnimGraphRuntime/Public/KismetAnimationLibrary.h — UKismetAnimationLibrary::CalculateDirection:225.
  • Runtime/AnimGraphRuntime/Public/AnimNodes/AnimNode_LayeredBoneBlend.h — FAnimNode_LayeredBoneBlend:21.
  • Plugins/Animation/MotionWarping/Source/MotionWarping/Public/MotionWarpingComponent.h — UMotionWarpingComponent:100, AddOrUpdateWarpTargetFromTransform:186.
  • Plugins/Animation/PoseSearch/Source/Runtime/Public/PoseSearch/PoseSearchLibrary.h — UPoseSearchLibrary:141, FMotionMatchingState:56.

Official docs (UE 5.8):

Deep-dive references:

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Ue Animation System AI skill do?

Animate skeletal meshes in Unreal using the AnimInstance / Animation Blueprint model — C++ UAnimInstance base class (NativeInitializeAnimation, NativeUpdateAnimation, NativeThreadSafeUpdateAnimation), AnimGraph with state machines and blend spaces, animation assets (UAnimSequence, UBlendSpace, UAnimMontage, UAnimComposite, UPoseAsset), anim notifies and notify states, montage playback and delegates, linked anim layers, Motion Matching (Pose Search plugin), and Motion Warping. Use when setting up character animation, driving locomotion blends from C++, playing montages for actions, firing ga...

Why use Ue Animation System on TypingMind?

Because you install it once and use it with any model. Ue Animation System is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Ue Animation System in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/kevinpbuckley/unreal-engine-skills/tree/master/skills/core/ue-animation-system. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Ue Animation System?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Ue Animation System?

As many as you like. As long as a model supports skills, you can use Ue Animation System with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Ue Animation System AI skill free?

It is published on GitHub by kevinpbuckley. Check the repository for licensing terms. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇