Skip to content

Examples & recipes

The SDK ships working example scripts you can drop in, read, and adapt. They live in AISDK/Examples/Scripts/ and Examples/ in your project. Each one is small and focused on a single pattern.

Greeting & world events

Script What it shows
GreeterTrigger Greet a player by username on enter and say goodbye on exit, from a trigger zone. Dual‑mode: on the NPC (NPC.Notify) or a separate object (NPC.NotifyTo).
IdentityGreeter Greet generically ("Hello there") while tracking returning visitors by their stable account id — identity without speaking a name.
WorldEventsNotifier Fire the common World Events at the NPC it's on (the companion to the Action Designer's Examples).
SharedWorldEvents Fire world events from a shared object (a door, a zone) to one or more NPCs via NPC.NotifyTo.

→ Background: World Events.

Players

Script What it shows
PlayerRoster React to OnPlayerJoined / OnPlayerLeft and read the live roster with Networking.GetPlayers() — the base for player‑list UI, teams, spectator tools.

→ Background: Player API.

Custom actions (the AI doing things)

Script What it shows
RoomLightsBehaviour Custom control of room lights — color, RGB, power — across three actions (OnSetLightColor, OnSetLightRGB, OnLightPower), each reporting back with NPC.CommandResult / CommandError.
StageDoorBehaviour A stateful custom action: open/close a sliding door (it remembers its state), using the Transform + AudioSource bindings — reading the scene, not just talking.
LabAssistantBehaviour Drive an AI NPC's automation without a player for testing — moves cubes, toggles a light.
AreaProbe Two ways for an NPC to know the live world: a context probe (WorldState(), ambient — always in the prompt) and an on‑demand query action (scan_area, "who's here?").

→ Background: Custom Actions.

Talking to a database

Script What it shows
SupabaseTest Full CRUD against Supabase with HTTP.Get/Post/Patch/Put/Delete in coroutines — health check, create/read/update a profile.
ScoreboardNpc End‑to‑end "what's my score?": Player.GetSpeakerUserId() keys a Supabase lookup, and an async action returns the number inline so the NPC speaks it in one turn.

→ Background: HTTP & Supabase.

Engine & Unity recipes

Copy‑paste companions for the Engine & Unity API guides — self‑contained, no scene wiring required.

Look-to-interact (physics + camera + input)

Raycast from the player's view; highlight whatever they're looking at and let them press E to use it. Pairs with Physics and Input, time & camera.

Put this on any always‑on object (an empty "GameController"):

using UnityEngine;
using NexusVM.Unity;

class LookToInteract : NexusBehaviour
{
    public float reach = 4f;     // how far the player can reach
    GameObject hovered;

    protected override void Update()
    {
        Camera cam = Camera.main;
        if (cam == null) return;

        // What is the player looking at, within reach?
        GameObject target = null;
        RaycastHit hit;
        if (Physics.Raycast(cam.transform.position, cam.transform.forward, out hit, reach)
            && hit.collider.CompareTag("Interactable"))
            target = hit.collider.gameObject;

        // Hover changed → tell the old and new objects
        if (target != hovered)
        {
            if (hovered != null) hovered.SendMessage("OnHoverExit");
            if (target  != null) target.SendMessage("OnHoverEnter");
            hovered = target;
        }

        if (hovered != null && Input.GetKeyDown("e"))
            hovered.SendMessage("OnUse");
    }
}

Put this on each interactable object (tag it Interactable, give it a Collider + Renderer):

using UnityEngine;
using NexusVM.Unity;

class Interactable : NexusBehaviour
{
    Renderer rend;
    Color baseColor;

    protected override void Start()
    {
        rend = GetComponent<Renderer>();
        baseColor = rend.GetColor();
    }

    public void OnHoverEnter() { rend.SetColor(Color.yellow); }   // highlight
    public void OnHoverExit()  { rend.SetColor(baseColor); }      // restore
    public void OnUse()        { Debug.Log(gameObject.name + " used!"); }
}

Teaches: Physics.Raycast + Camera.main, Collider.CompareTag, SendMessage between scripts, Input.GetKeyDown, and Renderer.SetColor/GetColor.

Score HUD (build UI from script)

A self‑contained heads‑up display that creates its own canvas, shows a score, and adds a +1 button — no scene UI to set up. Pairs with UI.

using UnityEngine;
using NexusVM.Unity;

class ScoreHud : NexusBehaviour
{
    int score;
    Text label;

    protected override void Start()
    {
        UI.EnsureEventSystem();                 // so the button receives clicks
        GameObject canvas = UI.CreateCanvas();

        // CreateLabel(parent, name, text, fontSize, posX, posY, sizeX, sizeY)
        label = UI.CreateLabel(canvas, "Score", "Score: 0", 32, 0, 420, 400, 60);

        // CreateButton(parent, name, label, posX, posY, sizeX, sizeY)
        Button add = UI.CreateButton(canvas, "Add", "+1", 0, -360, 160, 56);
        Button.AddClickListener(add, "OnAdd");  // calls OnAdd() below
    }

    public void OnAdd()
    {
        score++;
        Text.SetText(label, "Score: " + score);
    }
}

Teaches: UI.CreateCanvas/CreateLabel/CreateButton, click wiring with Button.AddClickListener(button, "Method"), and updating a label with Text.SetText. Swap the local score for a Storage or HTTP read to show shared state.

Common recipes

Resolve a player from a trigger:

void OnTriggerEnter(Collider other)
{
    string id = Player.IdOf(other.gameObject);   // "" if not a player
    if (id == "") return;
    // ... do something with id
}

Notify one or many NPCs from a shared object:

public GameObject[] targetNpcs;   // drag NPC(s) in the inspector

void Fire(string eventId, string json)
{
    if (targetNpcs == null || targetNpcs.Length == 0) NPC.Notify(eventId, json);
    else for (int i = 0; i < targetNpcs.Length; i++)
        if (targetNpcs[i] != null) NPC.NotifyTo(targetNpcs[i], eventId, json);
}

Track a player across sessions (durably): key your DB rows by Player.GetUserId and write with HTTP; use Storage as a same‑session cache.