> For the complete documentation index, see [llms.txt](https://finite-machine-studio.gitbook.io/vatmachine-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://finite-machine-studio.gitbook.io/vatmachine-documentation/runtime-scripting.md).

# Runtime Scripting

The main runtime components are:

[VATAnimator](/vatmachine-documentation/runtime-components/vatanimator.md)

[VATSocketLink](/vatmachine-documentation/runtime-components/vatsocketlink.md)

### Getting a VATAnimator Reference

The simplest way is to assign the `VATAnimator` in the Inspector.

```csharp
using UnityEngine;
using VATMachine.Runtime;

public class EnemyAnimationController : MonoBehaviour
{
    [SerializeField] private VATAnimator animator;

    private void Awake()
    {
        if (animator == null)
            animator = GetComponent<VATAnimator>();
    }
}
```

If your script is on a child object, you can also use:

```csharp
animator = GetComponentInParent<VATAnimator>();
```

### Playing Animations Directly

Use `Play` when you want to switch immediately to a state or animation.

```csharp
animator.Play("Idle");
animator.Play("Run");
animator.Play("Attack");
```

The name can be the VAT Animator Graph state name or the baked animation name.

Use `Crossfade` when you want a direct blend into another state without relying on graph transition rules.

```csharp
animator.Crossfade("Run", 0.2f);
animator.Crossfade("Attack", 0.1f);
```

`Play` is best for instant changes. `Crossfade` is best for scripted animation changes that still need a smooth blend.

### Using Parameters

`VATAnimator` supports Bool, Float, and Trigger parameters, similar to Unity's Animator.

#### Bool parameters:

```csharp
animator.SetBool("IsMoving", true);
animator.SetBool("IsMoving", false);

bool isMoving = animator.GetBool("IsMoving");
```

#### Float parameters:

```csharp
animator.SetFloat("Speed", 1.0f);
float speed = animator.GetFloat("Speed");
```

#### Trigger parameters:

```csharp
animator.SetTrigger("Attack");
animator.ResetTrigger("Attack");

bool attackQueued = animator.GetTrigger("Attack");
```

**Parameter names are case-sensitive. For example, "Speed" and "speed" are different names.**

Triggers remain active until they are consumed by a transition or reset manually.

### Checking Current State

You can read the current state and whether the animator is transitioning.

```csharp
if (animator.CurrentState != null)
{
    Debug.Log(animator.CurrentState.name);
}

if (animator.IsTransitioning)
{
    // Animator is currently blending between states.
}
```

This is useful for gameplay logic that needs to know what the VAT character is currently doing.

### Animation Events

VATMachine supports animation events inside the VAT Animator Graph. These events are useful for things that must happen at a specific animation frame, such as footsteps, attack hit frames, weapon sounds, VFX, object spawning, or gameplay callbacks.

Each event can have:

* Event Name
* Frame
* String Parameter
* Object Reference

The event name is usually used to decide what should happen. The string parameter and object reference are optional extra data you can pass to your script.

#### Receiving Animation Events

The recommended way is to subscribe to `AnimationEventTriggered` on the `VATAnimator`.

```csharp
using UnityEngine;
using VATMachine.Runtime;

public class VATAnimationEventReceiver : MonoBehaviour
{
    [SerializeField] private VATAnimator animator;
    [SerializeField] private AudioSource audioSource;

    private void Awake()
    {
        if (animator == null)
            animator = GetComponent<VATAnimator>();
    }

    private void OnEnable()
    {
        animator.AnimationEventTriggered += HandleAnimationEvent;
    }

    private void OnDisable()
    {
        animator.AnimationEventTriggered -= HandleAnimationEvent;
    }

    private void HandleAnimationEvent(VATAnimationEventContext context)
    {
        switch (context.Event.eventName)
        {
            case "Footstep":
                HandleFootstep(context);
                break;

            case "AttackHit":
                HandleAttackHit(context);
                break;

            case "PlaySound":
                HandlePlaySound(context);
                break;
        }
    }

    private void HandleFootstep(VATAnimationEventContext context)
    {
        string surfaceType = context.Event.stringParameter;

        Debug.Log("Footstep on: " + surfaceType);
    }

    private void HandleAttackHit(VATAnimationEventContext context)
    {
        string hitboxName = context.Event.stringParameter;

        Debug.Log("Attack hit frame reached. Hitbox: " + hitboxName);
    }

    private void HandlePlaySound(VATAnimationEventContext context)
    {
        AudioClip clip = context.Event.objectReference as AudioClip;

        if (clip != null && audioSource != null)
        {
            audioSource.PlayOneShot(clip);
        }
    }
}
```

#### Alternative: OnVATAnimationEvent Method

VATAnimator also sends events to components on the same GameObject using a method named `OnVATAnimationEvent`.

```csharp
using UnityEngine;
using VATMachine.Runtime;

public class VATEventReceiver : MonoBehaviour
{
    public void OnVATAnimationEvent(VATAnimationEventContext context)
    {
        switch (context.Event.eventName)
        {
            case "Footstep":
                Debug.Log("Footstep: " + context.Event.stringParameter);
                break;

            case "PlaySound":
                AudioClip clip = context.Event.objectReference as AudioClip;
                break;
        }
    }
}
```

#### Using String Parameter

The string parameter is useful when the same event needs different behaviour.

Example:

* Event Name: `Footstep`
* String Parameter: `Grass`

```csharp
private void HandleAnimationEvent(VATAnimationEventContext context)
{
    if (context.Event.eventName == "Footstep")
    {
        string surface = context.Event.stringParameter;

        Debug.Log("Play footstep for surface: " + surface);
    }
}
```

#### Using Object Reference

The object reference can point to a Unity object such as an AudioClip, prefab, ScriptableObject, material, or VFX asset.

Example:

* Event Name: `PlaySound`
* Object Reference: an `AudioClip`

```csharp
private void HandleAnimationEvent(VATAnimationEventContext context)
{
    if (context.Event.eventName == "PlaySound")
    {
        AudioClip clip = context.Event.objectReference as AudioClip;

        if (clip != null)
        {
            audioSource.PlayOneShot(clip);
        }
    }
}
```

This is useful when you want the animation event itself to decide which asset should be used.

### Blend Tree Events

If an event comes from a blend tree child motion, `context.IsBlendTreeMotionEvent` will be true.

```csharp
if (context.IsBlendTreeMotionEvent)
{
    Debug.Log("Event came from blend tree motion: " + context.BlendTreeMotion.animationName);
}
```

The event context also includes blend weight, which is useful if you want to ignore events from animations that barely influence the final pose.

### Using Socket Poses From Script

You can query socket poses from VATAnimator:

```csharp
if (animator.TryGetSocketWorldPose("RightHand", out Vector3 position, out Quaternion rotation))
{
    weapon.transform.SetPositionAndRotation(position, rotation);
}
```

You can also query the local socket pose:

```csharp
if (animator.TryGetSocketPose("RightHand", out VATSocketPose pose))
{
    // pose.LocalPosition
    // pose.LocalRotation
}
```

World pose is usually easier when controlling separate scene objects. Local pose is useful when you want to apply the result manually relative to the VATAnimator transform.

### Using VATSocketLink

`VATSocketLink` is used to make a GameObject follow a baked VAT socket at runtime. Most of its settings are configured in the Inspector, but you can still control the important parts from script.

The most common runtime use is switching the socket name. For example, a sword can switch from a hip socket to a hand socket during an animation event.

```csharp
using UnityEngine;
using VATMachine.Runtime;

public class VATWeaponSocketSwitcher : MonoBehaviour
{
    [SerializeField] private VATSocketLink socketLink;

    private const string HandSocket = "SwordHandHolder";
    private const string HipSocket = "SwordHipHolder";

    private void Awake()
    {
        if (socketLink == null)
            socketLink = GetComponent<VATSocketLink>();
    }

    public void AttachToHand()
    {
        socketLink.SocketName = HandSocket;
    }

    public void AttachToHip()
    {
        socketLink.SocketName = HipSocket;
    }
}
```

You can assign or change the target animator from script:

```csharp
socketLink.Animator = animator;
```

This is useful if the linked object is spawned at runtime and needs to connect to a specific `VATAnimator`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://finite-machine-studio.gitbook.io/vatmachine-documentation/runtime-scripting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
