# Animation System

Animation in Unreal Engine centers on three core assets: **Animation Blueprints** (state machines driving skeletal animation), **Anim Montages** (one-shot/layered animations played from code), and **Blend Spaces** (parameter-driven animation blending).

All Python asset creation uses `execute_python` with `import unreal`. Use `query_ue_api` to discover exact factory classes and property names before calling them.

## Animation Blueprint (ABP_)

An Animation Blueprint (ABP) is a specialized Blueprint that controls skeletal mesh animation. It contains a state machine (AnimGraph) and an event graph.

**Key concepts:**
- An ABP **requires a target Skeleton** — it cannot be created without one
- The Skeleton comes from a SkeletalMesh asset (e.g., your character mesh)
- ABP is linked to a character by setting `anim_class` on the character's SkeletalMeshComponent

**Creation workflow:**
1. Find the project's SkeletalMesh (use `list_files` or asset listing)
2. Load the mesh, extract its Skeleton
3. Use `query_ue_api('AnimBlueprintFactory')` to find the factory class
4. Create factory, set `target_skeleton`, create asset
5. Save the asset

**Linking ABP to a Character Blueprint:**
- Load the character Blueprint, find its SkeletalMeshComponent via SCS nodes
- Load the ABP asset and get its `generated_class()`
- Set the component's `anim_class` property to the ABP's generated class
- Compile and save the Blueprint

## AnimMontage (AM_)

An AnimMontage wraps an AnimSequence for code-driven playback with sections, branching, and notify support.

**Key concepts:**
- A Montage is always created FROM an existing AnimSequence
- Montages are played through the AnimInstance (via `Montage_Play`)
- Montages support sections (named segments) and branching between them
- Montage slots control which bones are affected (for layered animation)

**Creation workflow:**
1. Load the source AnimSequence asset
2. Use `query_ue_api('AnimMontageFactory')` to find the factory class
3. Create factory, set source_animation to the AnimSequence
4. Create asset, save it

### Play Montage in C++
```cpp
// In header
UPROPERTY(EditDefaultsOnly, Category = "Animation")
UAnimMontage* AttackMontage;

// In implementation
void AMyCharacter::PlayAttack()
{
    if (UAnimInstance* AnimInst = GetMesh()->GetAnimInstance())
    {
        AnimInst->Montage_Play(AttackMontage, 1.0f);
    }
}

// With delegate for montage end
void AMyCharacter::PlayAttackWithCallback()
{
    if (UAnimInstance* AnimInst = GetMesh()->GetAnimInstance())
    {
        FOnMontageEnded EndDelegate;
        EndDelegate.BindUObject(this, &AMyCharacter::OnAttackMontageEnded);
        AnimInst->Montage_Play(AttackMontage);
        AnimInst->Montage_SetEndDelegate(EndDelegate, AttackMontage);
    }
}

void AMyCharacter::OnAttackMontageEnded(UAnimMontage* Montage, bool bInterrupted)
{
    // Handle montage completion
}
```

## BlendSpace (BS_)

A BlendSpace blends between animations based on input parameters (e.g., character speed, direction).

**Types:**
- **BlendSpace1D** — single axis (e.g., speed: Idle at 0, Walk at 150, Run at 375)
- **BlendSpace** (2D) — two axes (e.g., speed + direction for omnidirectional locomotion)

**Key concepts:**
- BlendSpaces also require a target Skeleton (same as ABP)
- Sample points map parameter values to specific AnimSequences
- The AnimBlueprint reads gameplay variables and feeds them as BlendSpace parameters

**Creation workflow:**
1. Determine 1D vs 2D based on the animation need
2. Use `query_ue_api('BlendSpaceFactory')` to find the factory class
3. Create the factory, set `target_skeleton` from the project's SkeletalMesh
4. Create the asset, save it
5. Sample points (animation mappings) can be set via editor properties — use `dir()` on the created asset to discover the API

## Anim Notifies

Anim Notifies fire events at specific frames in an animation:
- **AnimNotify_PlaySound** — play a sound at a frame
- **AnimNotify_PlayParticleEffect** — spawn particles
- Custom AnimNotify — C++ class deriving from `UAnimNotify`, override `Notify()`
- **AnimNotifyState** — has Begin/End for duration-based effects (trail, damage window)

### Custom AnimNotify in C++
```cpp
UCLASS()
class UAN_DamageWindow : public UAnimNotifyState
{
    GENERATED_BODY()

public:
    virtual void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
        float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
    virtual void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation,
        const FAnimNotifyEventReference& EventReference) override;
};
```

## Naming Conventions
- **ABP_** prefix for Animation Blueprints: ABP_MyCharacter, ABP_Enemy
- **AM_** prefix for Montages: AM_Attack, AM_Dodge, AM_Death
- **BS_** prefix for BlendSpaces: BS_Locomotion, BS_AimOffset
- **AN_** prefix for custom AnimNotifies: AN_DamageWindow, AN_FootStep

## CRITICAL RULES
- AnimBlueprint REQUIRES a target Skeleton — always discover and set it before creation
- ALWAYS verify the skeleton/mesh exists before creating any animation asset (ABP, BlendSpace)
- Set `anim_class` on SkeletalMeshComponent to link ABP to a character
- `Montage_Play` returns duration (0.0 = failed) — always check the return value
- Use `query_ue_api` to discover factory classes and property names — do NOT guess them
- Use `dir()` on loaded assets/factories to discover available properties and methods at runtime
