Appearance
Events
Events trigger scripts. Scenery has two kinds: object events that fire for a specific object, and scene events that fire globally.
Object events
Attach to individual objects. The triggering object is available in scriptContext.sourceEvent.
| Event | Fires when |
|---|---|
| On Will Appear | Object is about to be added to scene |
| On Did Appear | Object has appeared |
| On Removal | Object is removed from scene |
| On Tap Gesture | Object is tapped |
| On Camera Collision | Camera enters/exits object bounds |
| On Object Collision | Physics collision with another object |
| Distance Field | Camera or target crosses distance threshold |
| Look Direction | User looks at/away from object (or object looks at target) |
| Media Playback | Video/audio begins, reaches timestamp, or ends |
javascript
// On Tap Gesture – scale up the tapped object
scriptContext.sourceEvent.objectEntity.animateTo(
{ scale: Vector3(1.2, 1.2, 1.2) },
0.2
);Scene events
Fire regardless of which object is involved.
| Event | Fires when |
|---|---|
| On Experience Start | Experience begins |
| On Experience Load | Experience finishes loading |
| On Screen Tap | User taps anywhere on screen |
| On Render | Every frame |
| On Schedule | After a delay or at specific time |
| On Variable Change | A variable is modified |
| On Audio Analysis | Audio levels update (ambient or microphone) |
javascript
// On Render – rotate every frame
var cube = scene.findEntity("YOUR_OBJECT_ID");
cube.representation.rotation = cube.representation.rotation.multiply(
Rotation(0, scriptContext.sourceEvent.deltaTime, 0)
);Subscribing in code
You can also subscribe to events programmatically:
javascript
var cube = scene.findEntity("YOUR_OBJECT_ID");
// Object event
cube.on('tap', function(e) {
e.objectEntity.animateTo({ scale: Vector3(1.2, 1.2, 1.2) }, 0.2);
});
// Scene event
scene.on('render', function(e) {
cube.representation.rotation = cube.representation.rotation.multiply(
Rotation(0, e.deltaTime, 0)
);
});
// One-time listener
scene.once('start', function() {
console.log('Experience started');
});Throttling
For expensive operations, throttle the render loop:
javascript
scene.on('render', { throttle: 0.1 }, function(e) {
// Runs every 100ms instead of every frame
});Unsubscribing
javascript
var eventId = cube.on('tap', function() {});
// Later...
cube.off(eventId);objectEntity vs representationEntity
Tap and collision events give you both objectEntity (the top-level container) and representationEntity (the specific visual that was interacted with). Use objectEntity when you need to find sibling representations like audio sources.
Event data
How you access event data depends on how your script runs:
Run Script action – use scriptContext.sourceEvent:
javascript
var entity = scriptContext.sourceEvent.objectEntity;
var dt = scriptContext.sourceEvent.deltaTime;Event subscriptions – data is passed to your callback:
javascript
scene.on('render', function(e) {
var dt = e.deltaTime;
});
cube.on('tap', function(e) {
var tapped = e.objectEntity;
});Properties by event type:
| Event | Properties |
|---|---|
render | deltaTime, time |
tap | objectEntity, representationEntity, screenPosition |
screenTap | position |
distance | objectEntity, distance, crossed |
lookAt | objectEntity, isLooking |
cameraCollision | objectEntity, representationEntity |
physicsCollision | objectEntity, representationEntity, position, impulse |
variableChange | variableId, value |
mediaPlayback | objectEntity, status, time, duration |
audioAnalysis | kind, loudness, bass, lowMid, mid, upperMid, presence, brilliance, air, treble |
add, appear, remove | objectEntity, representationEntity |
TIP
Use console.log(scriptContext.sourceEvent) or console.log(e) to inspect all available properties.