Dynamic context usage examples
Five Dynamic Context examples show a relay-driven trigger, a batched update, an event log, an emergency transition, and synced world-object context.
The following examples progress from a single relay-driven trigger to scripted batch updates and synced world-object context. Each example lists the scenario context, the concrete Inspector or script setup, and the expected runtime outcome.
Safety drill: station tracking
Context: A fire suppression certification drill. A trainer NPC guides operators through suppression stations. The character must always know the operator's current station to give station-specific instructions and hazard warnings.
Setup (Relay + trigger script)
Add
ConvaiDynamicContextRelayto the trainer NPC's GameObject (Convai → Dynamic Context → Convai Dynamic Context Relay).In the Defaults section, set Reaction Mode to
MustRespond— the character should acknowledge every station change.Enable Flush Immediately so each station change is sent right away instead of waiting for the normal batch window.
Add a small trigger script to each station's trigger volume, pointing every instance at the same relay:
using Convai.Runtime.Presentation.DynamicContext;
using UnityEngine;
public class StationZoneTrigger : MonoBehaviour
{
[SerializeField] private ConvaiDynamicContextRelay _relay;
[SerializeField] private string _stationName;
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
_relay.SetState("Station", _stationName);
}
}Set Station Name to the zone's label, for example
Fire Suppression Bay, and repeat for each additional station.
ConvaiDynamicContextRelay.SetState takes both a state name and a value, so it cannot be bound directly from a UnityEvent in the Inspector the way a single-parameter method can. The trigger script above supplies the name and per-zone value at runtime; the relay resolves the trainer's ConvaiCharacter and applies the configured reaction mode.
Expected outcome
When the operator enters the Fire Suppression Bay trigger, StationZoneTrigger calls SetState("Station", "Fire Suppression Bay") on the relay. The relay stages the state with MustRespond and flushes immediately:
"You've arrived at the Fire Suppression Bay. With the current extreme hazard rating, confirm your PPE is on before touching any equipment."
The Station state persists in the local tracker. If the operator asks "Where am I?" at any point, the character answers with the current station value.
Onboarding walkthrough: batch state update
Context: A corporate onboarding simulation. An HR representative NPC adapts its guidance based on which items a new employee has collected and which checkpoints they have cleared. Two conditions are met at the same moment — send them in one call so the character reacts to both together.
Setup (Scripting)
Expected outcome
OnAccessCardAndBriefingComplete() stages both states in one call. The SDK batches staged updates for up to ConvaiCharacter.DynamicContextBatchDelaySeconds (0.5 seconds by default) before sending one canonical rebuild to Convai. Because MustRespond was requested, the HR character responds once the batch flushes:
"You've collected your access card and completed the security briefing — you're cleared for floor access. Head to Workstation 4B next."
TryGetStateValue reads from the local tracker with no network round-trip. It returns the current value if the state was set, or false if it was never set or has been removed.
Guided tour: exhibit tracking and visitor events
Context: A museum guided tour. A docent NPC tracks which exhibit is currently active and records visitor interactions as chronological events, then uses that history to give personalized recommendations.
Setup (Two relay instances)
ConvaiDynamicContextRelay allows only one instance per GameObject, so each relay with a different default reaction mode lives on its own child GameObject of the docent NPC.
Child GameObject 1 — "ExhibitRelay"
Add
ConvaiDynamicContextRelay.Target → Auto Resolve Character: disabled; Character: the docent's
ConvaiCharacter— the relay is on a child GameObject, not the character's own GameObject.Defaults → Reaction Mode:
Silent— the exhibit name updates without an immediate response; tour narrative drives pacing.Add a trigger script (the same pattern as
StationZoneTriggerin the first example) to each exhibit's trigger volume, calling_relay.SetState("ActiveExhibit", _exhibitName)and pointing every instance at this relay.
Child GameObject 2 — "EventRelay"
Add
ConvaiDynamicContextRelay.Target → Auto Resolve Character: disabled; Character: the docent's
ConvaiCharacter.Defaults → Reaction Mode:
Auto— Convai decides whether a logged interaction is worth an immediate response.Wire UI buttons directly to
AddEvent.AddEventtakes a single string parameter, so it binds from a button's On Click () with a static string argument — no script required. Bind one button toEventRelay → AddEventwith the argumentVisitor asked about the Colosseum reconstruction, and a second button toAddEventwithVisitor photographed the gladiator exhibit.
Expected outcome
As the visitor progresses, the docent's canonical context accumulates:
The docent references both the current exhibit and the visitor's specific interactions:
"Since you photographed the gladiator exhibit, you might enjoy the additional display on Roman military equipment in the next room."
Emergency response: multi-state transition and reaction escalation
Context: An industrial safety simulation. A supervisor NPC must respond to a simultaneous shift from routine inspection to emergency mode — three state changes and one logged event happen together, and the character must acknowledge all of them in a single response.
Setup (Scripting)
Expected outcome
Both calls stage inside the same debounce window — up to ConvaiCharacter.DynamicContextBatchDelaySeconds (0.5 seconds by default) after the first staged change. The tracker combines the three states and the event into one canonical rebuild and keeps the strongest reaction requested across the batch (MustRespond outranks Silent), so the character produces exactly one response covering all four changes:
"Chemical leak at Bay 7 — all personnel evacuate the east wing immediately. Bay 7 ventilation is engaged. Do not re-enter until the all-clear is given."
Calling SetStates for the three simultaneous transitions, instead of three sequential SetState calls, keeps the changes together in the delta line the character uses to narrate the transition. The AddEvent call adds the alarm as a separate chronological line without lowering the reaction already requested for the batch.
Synced world-object context: shared equipment status
Context: An industrial safety simulation with two NPCs on the factory floor — a supervisor and a safety instructor. Both characters must be aware of a pressure valve's open or closed state without either character's script polling the valve directly.
Setup (World object with a tracked property)
Add
ConvaiObjectMetadatato the valve's GameObject (Convai → World Object, or search "Convai World Object" in Add Component).Set Object Name to
PressureValveand Object Description to a factual description of the valve's location.In Tracked Properties, add one
ConvaiTrackedContextPropertyentry:Property Name:
StatusSource Component: the valve's controller script
Source Member Name: the name of the public property or field that reports the current state, for example
StatusInitial Value:
Closed— used only if the reflection read failsReaction:
Auto— let Convai decide whether the state change is worth mentioning
The SDK polls every tracked property that has a Source Component on a shared timer. When ValveController.Status changes, ConvaiObjectMetadata broadcasts the updated value to every connected character — not only one — using the state key PressureValve.Status.
Expected outcome
Once the valve opens, both the supervisor and the safety instructor receive the same state update:
Either NPC can now reference the valve without a dedicated script feeding it — for example, the supervisor: "The pressure valve is open — hold position until it's confirmed closed." Disabling or removing the ConvaiObjectMetadata component removes the PressureValve.Status state from every character that was tracking it.
Next steps
Relay component referenceDynamic context scripting APISync behavior and timingScene metadataLast updated
Was this helpful?