Documentation index for AI agents (llms.txt) A Markdown version of every page is available: request the page's source under /docs/, follow the "alternate" link in this page's head, or start from /llms.txt.
Visual Script logo Scripting API

Args#

Args is the pooled execution context passed to every Instruction, Condition, Trigger, and Signal. It carries Source, Target, and named parameters so nested logic can act on the current objects and values.

What it carries#

The context identifies the objects involved and carries any extra values the running logic needs:

Member Is
Source The GameObject the running logic belongs to — for a Trigger, the object holding the Event.
Target The other GameObject involved.
Parameters Named, typed extra values — loop item, index, count, and anything you add.

This Instruction reads the current Target from its context:

protected override Awaitable Run(Args args)
{
    GameObject who = args.Target;
    Debug.Log($"Acting on {who.name}");

    return Done;
}

args.Target resolves to the other object supplied by the Trigger or caller. Designers use the same context through Source & Target.

Args instances are pooled#

Args instances are recycled. Reading one after release produces values from a later use rather than an exception.

Never construct one directly. Get one from the pool and dispose it:

using Args args = Args.Get(this.gameObject, target);
this.m_Instructions.Run(args, this);

The using declaration returns the instance to the pool at the end of the scope. Use the same ownership pattern for every acquired instance.

Never store an Args reference

Caching an Args in a field, capturing it in a long-lived closure, or holding it across frames means you're reading whatever the pool later put in that slot.

When context must survive inside a subscription, copy it with Args.Get(args). The copy is independent and must be disposed when the subscription ends.

In the editor, accessing a disposed Args logs an error. Builds omit this check, so fix every reported use-after-release before shipping.

Getting one#

Overload Use when
Args.Get() You need an empty context.
Args.Get(source, target) You have both objects. Accepts GameObject or Component.
Args.Get(args) You need an independent copy of an existing context.
Args.None You need a shared, permanently empty context. Never dispose it.

Args.None is a singleton for context-free calls. Because it's shared, don't write to it.

Reading components#

Two shortcuts avoid a GetComponent on every access:

Rigidbody body = args.TargetComponent<Rigidbody>();
Animator anim = args.SourceComponent<Animator>();

TargetComponent and SourceComponent use a per-object component cache, avoiding repeated Unity lookups after the first successful search.

Parameters#

Beyond Source and Target, Args carries named values. Foreach uses parameters for the current item, and custom Instructions use them to pass data into nested lists:

args.SetParameter(MY_PARAMETER, someValue);

if (args.TryGetParameter(MY_PARAMETER, out int value))
{
    // …
}

SetParameter stores an exact type under a PropertyName. Read with TryGetParameter when the type must match, or TryConvertParameter when conversion is valid.

Method Does
SetParameter<T>(id, value) Stores a typed value.
TryGetParameter<T>(id, out value) Reads it back, requiring an exact type match.
TryConvertParameter<T>(id, out value) Reads it back, converting if needed.
ContainsParameter(id) Tests presence.
ClearParameter(id) Removes it.
GetParameterGameObject(id) Reads it as a GameObject, unwrapping a Component if necessary.

Identifiers are PropertyName values, which compare by hash rather than by string. Declare them once as static readonly fields; do not build them per call.

Collection loops use the parameters defined in ArgsCollectionParameters: item, index, and count.

Declaring a parameter scope#

For a parameter to appear in the Signal dropdowns of a nested list, the containing Instruction declares which of its fields provide it:

bool IParameterScope.ProvidesParameter(string member, PropertyName parameter)
{
    return member == nameof(this.m_Instructions)
        && ArgsCollectionParameters.Contains(parameter);
}

Without this declaration, code can still read the value at runtime, but designers can't select it in the nested list's Signal dropdowns.

Copying and nesting#

Args.Get(args) copies Source, Target, and every set parameter into a fresh instance. Nested lists use this so that changes made inside a loop don't affect the outer context.

Foreach is the canonical example: it copies the context, overwrites Target per iteration, and the outer context is untouched when the loop ends.

Where to go next#

Visual Script logoVisual Script © Catsoft Works 2026. All rights reserved.