Skip to main content

Triggers

Triggers are story nodes that wait for something to happen in the VR experience. Use them to detect grabs, touches, placements, collisions, UI clicks, physical button presses, ray pointer events, or custom scripted events.

Each trigger uses the same core fields:

NameThe trigger node type selected in StoryCreator.

QueryThe watched GameObjectQuery or system object.

OptionThe event mode selected in Unity. Each option is explained under the trigger entry.

DataExtra option-specific fields shown in Unity, such as hand selection, target object names, bounds, hold duration, or collision targets.

TypeUnused legacy field. Keep it as 1 for triggers.

Hand and Object Interaction Triggers

HandTouchTrigger

Detects when a hand touches or stops touching an object.

Query and Scene Setup

QueryTouchable object with HandTouchDetectable or compatible item behavior.

Scene setupAdd Touchable_Block.prefab or convert the mesh to a touch object.

Options

Touch

Fires when the configured hand condition starts touching the object. If the condition is already met when the trigger begins, it can complete immediately.

Untouch

Fires when the configured hand condition stops touching the object.

handOptionAccepted hand filter: Any, Left, Right, or Both.

JSON example
{
"Name": "HandTouchTrigger",
"Query": "StartButton",
"Option": "Touch",
"Data": "{\"handOption\":\"Any\"}",
"Type": 1
}

GrabbableTrigger

Detects grab, release, or use events on grabbable objects.

Query and Scene Setup

QueryGrabbable object with IGrabbableWrapper.

Scene setupAdd Grabbable_Block.prefab or convert the mesh to a grabbable object.

Options

Grab

Fires when the object is grabbed by an allowed hand.

Release

Fires when the object is released by an allowed hand.

Used

Fires when the held object is used or squeezed by an allowed hand.

handOptionAccepted hand filter: Any, Left, Right, or Both.

JSON example
{
"Name": "GrabbableTrigger",
"Query": "Wrench",
"Option": "Grab",
"Data": "{\"handOption\":\"Right\"}",
"Type": 1
}

PlacePointTrigger

Detects when objects are placed in or removed from place points.

Query and Scene Setup

QueryThe place point object being watched. It must have IPlacePointWrapper.

Scene setupAdd Placepoint_Block.prefab or MetaXRPlacePoint.prefab. The expected grabbable must also be queryable and have IGrabbableWrapper.

Options

Place

Fires when the named grabbable is placed on the place point.

grabbableNameGameObjectQuery name of the grabbable expected at the place point.

enableGrabWhether the grabbable remains grabbable while this trigger is active.

createGhostMeshIf true, creates a ghost preview for the expected object.

deleteGhostMeshOnPlaceIf true, removes the ghost preview after placement.

Remove

Fires when the named grabbable is removed from the place point.

grabbableNameGameObjectQuery name of the grabbable to watch for removal.

CorrectPlace

Fires when the place point receives its configured correct object.

WrongPlace

Fires when the place point receives an object that is not the configured correct object.

CorrectRemove

Fires when the correct object is removed.

WrongRemove

Fires when a wrong object is removed.

createGhostMeshFor correct/wrong placement variants, the place point can create a custom ghost mesh.

deleteGhostMeshOnPlaceRemoves ghost preview after placement when enabled.

JSON example
{
"Name": "PlacePointTrigger",
"Query": "ToolTrayPlacePoint",
"Option": "CorrectPlace",
"Data": "{\"grabbableName\":\"Wrench\",\"createGhostMesh\":true,\"deleteGhostMeshOnPlace\":true}",
"Type": 1
}

Collision and Spatial Triggers

CollisionTrigger

Detects solid or trigger-based collisions between objects.

Query and Scene Setup

QueryObject that owns the collision listener. The SDK adds ObjectCollisionDetector if needed.

Scene setupConfigure colliders and rigidbodies for the desired Unity physics mode. The target collision object must be queryable.

Options

Enter

Fires when the query object begins collision or trigger contact with the target object.

Exit

Fires when the query object stops collision or trigger contact with the target object.

targetCollisionGameObjectGameObjectQuery name of the object that must collide with the query object.

isTriggerIf true, listens to trigger events. If false, listens to collision events.

Stay

Fires when the query object remains in collision or trigger contact with the target object. Can require a minimum stay time.

targetCollisionGameObjectGameObjectQuery name of the object that must stay in contact.

isTriggerIf true, listens to trigger stay events. If false, listens to collision stay events.

stayTimeOptional seconds the contact must remain active before the trigger completes. Defaults to immediate stay behavior.

JSON example
{
"Name": "CollisionTrigger",
"Query": "ProbeTip",
"Option": "Stay",
"Data": "{\"targetCollisionGameObject\":\"InspectionArea\",\"isTrigger\":true,\"stayTime\":2}",
"Type": 1
}

CollisionAndUseTrigger

Detects a continuous collision plus a use/squeeze action.

Query and Scene Setup

QueryCollision/use area.

Scene setupAdd CollisionAndUseArea_Block.prefab or configure an equivalent collision area.

Options

StayAndUse

Fires when the target object is staying in the collision area and the user performs the use/squeeze action.

targetCollisionGameObjectObject that must stay in collision with the query object.

JSON example
{
"Name": "CollisionAndUseTrigger",
"Query": "ToolUseArea",
"Option": "StayAndUse",
"Data": "{\"targetCollisionGameObject\":\"Tool\"}",
"Type": 1
}

AnyTrigger

Observes global interactions and can filter out specific objects or trigger types.

Query and Scene Setup

QueryUsually blank. This is a global observer.

Scene setupNo dedicated prefab required.

Options

Empty option

AnyTrigger behavior is controlled by data filters instead of a dropdown option.

ignoreQueriesList of object query names to ignore.

ignoreTriggerTypesList of trigger interaction types to ignore.

triggerFromCount index to start firing from.

triggerIntervalInterval between firings. Default is continuous behavior.

triggerOnceIf true, fires only once.

ignoreOnRightTriggersIf true, ignores right-action trigger events.

JSON example
{
"Name": "AnyTrigger",
"Query": "",
"Option": "",
"Data": "{\"ignoreQueries\":[\"SafeObject\"],\"ignoreTriggerTypes\":[],\"triggerOnce\":true}",
"Type": 1
}

UI and Response Triggers

MCQResponseTrigger

Detects when the user responds to an MCQ evaluation panel.

Query and Scene Setup

QueryMCQ panel configured by MCQResponseAction. It must have MCQEvaluationHandler.

Scene setupAdd an MCQ panel prefab with MCQEvaluationHandler.

Options

AnyResponse

Fires when the learner submits any response.

CorrectResponse

Fires only when the submitted response is correct.

WrongResponse

Fires only when the submitted response is wrong.

FieldsNo option-specific data fields. Filtering is controlled by the selected option.

JSON example
{
"Name": "MCQResponseTrigger",
"Query": "MCQPanel",
"Option": "CorrectResponse",
"Data": "{}",
"Type": 1
}

UIButtonTrigger

Detects click events from a Unity UI Button component.

Query and Scene Setup

QueryGameObject with a Unity UI Button.

Scene setupAdd UIButtonWithCanvas_Block.prefab or ButtonVRseUI.prefab.

Options

OnClick

Fires when the Unity UI Button onClick event runs.

FieldsNo option-specific data fields.

JSON example
{
"Name": "UIButtonTrigger",
"Query": "ContinueButton",
"Option": "OnClick",
"Data": "{}",
"Type": 1
}

Specialized Mechanic Triggers

ForcepsTrigger

Detects forceps-specific grab and release events.

Query and Scene Setup

QueryForceps object.

Scene setupAdd Forceps_Block.prefab from VRseBlocks.

Options

Grab

Fires when the forceps grabs the configured object.

Release

Fires when the forceps releases the configured object.

grabbableNameTarget object the forceps should grab or release.

placePointNameGOTarget place point used by the forceps mechanic.

JSON example
{
"Name": "ForcepsTrigger",
"Query": "Forceps",
"Option": "Grab",
"Data": "{\"grabbableName\":\"CottonBall\",\"placePointNameGO\":\"TrayPlacePoint\"}",
"Type": 1
}

TransformBoundsTrigger

Monitors transform movement or rotation against configured bounds.

Query and Scene Setup

QueryTransform Bounds block with ITransformBounds.

Scene setupAdd the matching MetaXRTransformBounds_*_Block.prefab from VRseBlocks.

Options

Single

Fires when one named bound is reached.

boundTypeThe specific bound to watch, such as a min/max position or rotation bound from the Transform Bounds component.

lockOnReachIf true, lock the transform when the bound is reached.

snapToExactBoundsIf true, snap exactly to the bound when locking.

Combination

Fires when an existing named bound combination completes.

combinationNameName of an existing combination configured on the Transform Bounds component.

lockOnReachIf true, lock when the combination completes.

snapToExactBoundsIf true, snap exactly to bounds when locking.

CustomCombination

Creates a temporary combination from JSON data and fires when all specified bounds are satisfied.

boundsArray of bound names included in the custom combination.

lockOnReachIf true, lock when the custom combination completes.

snapToExactBoundsIf true, snap exactly to bounds when locking.

Any

Fires when any bound on the object is reached.

lockOnReachIf true, lock when any bound is reached.

snapToExactBoundsIf true, snap exactly to the reached bound when locking.

Repetition

Fires when an existing repetition event completes.

eventNameName of an existing repetition event configured on the Transform Bounds component.

CustomRepetition

Creates a repetition event and fires when it completes.

eventNameName for the repetition event.

primaryBoundTypeFirst bound in the repeated movement pair.

counterBoundTypeSecond bound in the repeated movement pair.

requiredRepetitionsNumber of repetitions required. Defaults to 3 if not provided.

timeWindowAllowed time window. Defaults to 5 seconds if not provided.

resetOnTimeoutIf true, resets repetition progress when time expires.

lockOnReachIf true, locks after completion.

snapToExactBoundsIf true, snaps when locking.

JSON example
{
"Name": "TransformBoundsTrigger",
"Query": "SlidingDrawer",
"Option": "Single",
"Data": "{\"boundType\":\"Max\",\"lockOnReach\":true,\"snapToExactBounds\":true}",
"Type": 1
}

PlaceAndAnimateTrigger

Waits for a place-and-animate path to complete.

Query and Scene Setup

QueryObject with IPlaceAndAnimate.

Scene setupAdd PlaceAndAnimate_Block.prefab from VRseBlocks.

Options

Empty option

Waits for the component's path completion event.

FieldsNo option-specific data fields.

JSON example
{
"Name": "PlaceAndAnimateTrigger",
"Query": "AnimatedToolPath",
"Option": "",
"Data": "{}",
"Type": 1
}

PivotRotateLimiterTrigger

Detects when a rotatable object reaches configured rotation limits.

Query and Scene Setup

QueryPivot Rotate Limiter block with IPivotRotateLimiter.

Scene setupAdd the matching MetaXRPivotRotateLimiter_*Axis_Block.prefab from VRseBlocks.

Options

Min

Fires when the object reaches its minimum rotation limit.

Max

Fires when the object reaches its maximum rotation limit.

lockOnReachIf true, locks rotation when the limit is reached.

Specific

Fires when the object reaches a specific rotation value.

specificPositionRotation value to watch for.

lockOnReachIf true, locks rotation when the value is reached.

JSON example
{
"Name": "PivotRotateLimiterTrigger",
"Query": "ValveWheel",
"Option": "Max",
"Data": "{\"lockOnReach\":true}",
"Type": 1
}

PhysicalButtonTrigger

Detects pressable physical button interactions.

Query and Scene Setup

QueryPhysical button object with IPhysicalButton.

Scene setupAdd MetaXRPhysicalButton_Block.prefab. Add ProgressBar.prefab if using hold progress display.

Options

Press

Fires when the physical button is pressed.

Unpress

Fires when the physical button is released/unpressed.

FieldsNo option-specific data fields.

Hold

Fires after the button is held for the configured duration.

holdDurationSeconds the button must be held.

enableHapticsIf true, plays controller haptic feedback during hold.

hapticAmplitudeHaptic strength.

enableSfxIf true, plays SFX during hold feedback.

sfxPathRequired when enableSfx is true.

enableProgressBarIf true, displays hold progress.

progressBarQuery name of a ProgressBar object. Required when enableProgressBar is true.

JSON example
{
"Name": "PhysicalButtonTrigger",
"Query": "EmergencyStopButton",
"Option": "Hold",
"Data": "{\"holdDuration\":2.0,\"enableHaptics\":true,\"enableProgressBar\":true,\"progressBar\":\"HoldProgressBar\"}",
"Type": 1
}

RayPointerTrigger

Detects ray pointer hover, selection, and hold interactions.

Query and Scene Setup

QueryRay-interactable object with IRayPointerInteractable.

Scene setupConvert or add a ray-interactable object. Add ProgressBar.prefab if using hold progress display.

Options

Hover

Fires when the ray starts hovering over the object.

Unhover

Fires when the ray stops hovering over the object.

Select

Fires when the ray selects the object.

Unselect

Fires when the ray unselects the object.

FieldsNo option-specific data fields.

Hold

Fires after the ray pointer holds on the object for the configured duration.

holdDurationSeconds the pointer must hold.

enableHapticsIf true, plays controller haptic feedback.

hapticAmplitudeHaptic strength.

enableSfxIf true, plays SFX during hold feedback.

sfxPathRequired when enableSfx is true.

enableProgressBarIf true, displays hold progress.

progressBarQuery name of a ProgressBar object. Required when enableProgressBar is true.

JSON example
{
"Name": "RayPointerTrigger",
"Query": "RemoteButton",
"Option": "Select",
"Data": "{\"enableHaptics\":true,\"enableSfx\":false}",
"Type": 1
}

Custom Trigger

ScriptableTrigger

Waits for a custom event from a ScriptableTriggerInvoker.

Query and Scene Setup

QueryObject with ScriptableTriggerInvoker.

Scene setupCreate a script inheriting from ScriptableTriggerInvoker and invoke its event when your custom condition is met.

Options

Empty option

Waits for the custom invoker event.

FieldsNo option-specific data fields.

JSON example
{
"Name": "ScriptableTrigger",
"Query": "CustomTriggerInvoker",
"Option": "",
"Data": "{}",
"Type": 1
}