Trigger Areas
Trigger areas allow you to react to the event of a player entering or leaving an area, or of any other entity entering or leaving an area. This is a fundamental tool for creating interactive scenes. Use them for things like opening a door when the player approaches, or to score a point when a ball enters a goal.
Using trigger areas #
To use trigger areas you need to add a TriggerArea
component to an entity, then use a triggerAreaEventsSystem
to react to the events.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity)
Transform.create(triggerEntity, {
position: Vector3.create(8, 0, 8),
scale: Vector3.create(1, 1, 1),
})
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
console.log('Player entered trigger area!')
})
Trigger area shapes #
Trigger areas can be either a box or a sphere.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
// Box
TriggerArea.setBox(triggerEntity)
// Sphere
TriggerArea.setSphere(triggerEntity)
💡 Tip: The sphere is the easiest shape to calculate for the engine, as it’s achieved by checking the distance from the center of the sphere. If in doubt, use a sphere.
To alter the size of the trigger area, you can use the scale
property of the Transform
component on the entity holding the TriggerArea
.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity)
Transform.create(triggerEntity, {
scale: Vector3.create(4, 2, 4),
})
Debugging #
To debug your scene and see the area covered by the trigger area, you can add a MeshShape
component to the entity with the trigger area, and set the shape to the one you want to debug. The dimensions of the default mesh will match the dimensions of the trigger area.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity)
MeshShape.setBox(triggerEntity)
Transform.create(triggerEntity, {
position: Vector3.create(8, 0, 8),
})
Trigger area events #
You can use the triggerAreaEventsSystem
to react to the different events of a trigger area:
onTriggerEnter
: Triggered when an entity enters the trigger area.onTriggerExit
: Triggered when an entity leaves the trigger area.onTriggerStay
: Triggered while an entity is in the trigger area, every frame.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity)
// On enter
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
console.log('Player entered trigger area!')
})
// On exit
triggerAreaEventsSystem.onTriggerExit(triggerEntity, function(result) {
console.log('Player exited trigger area!')
})
// On stay
triggerAreaEventsSystem.onTriggerStay(triggerEntity, function(result) {
console.log('Player is in trigger area!')
})
Trigger event responses #
When a trigger area event is triggered, you can use the result
parameter to get information about both the entity that was triggered and the entity that triggered the event.
The following properties are available in the result
parameter:
triggeredEntity
: The ID of the entity that was triggered (this is the entity that owns the trigger area)triggeredEntityPosition
: The position of the entity that was triggeredtriggeredEntityRotation
: The rotation of the entity that was triggeredeventType
: The type of trigger event (ENTER, EXIT, STAY)timestamp
: The timestamp of the trigger eventtrigger
: An object with the following fields:entity
: The ID of the entity that triggered the trigger (the entity that entered the trigger area)layer
: The collision layer of the entity that triggered the triggerposition
: The position of the entity that triggered the triggerrotation
: The rotation of the entity that triggered the triggerscale
: The scale of the entity that triggered the trigger
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
// Trigger area
const triggeredEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity)
Transform.create(triggerEntity, {
position: Vector3.create(8, 0, 8),
})
// Entity that will trigger the trigger area
const triggerEntity = engine.addEntity()
const triggeredEntity = engine.addEntity()
Transform.create(triggeredEntity, {
position: Vector3.create(8, 0, 8),
})
// On enter
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
console.log('An entity entered trigger area!', result.triggeredEntity)
console.log('Triggered entity position: ', result.triggeredEntityPosition)
console.log('Triggered entity rotation: ', result.triggeredEntityRotation)
console.log('Event type: ', result.eventType)
console.log('Timestamp: ', result.timestamp)
console.log('Trigger entity: ', result.trigger.entity)
console.log('Trigger layer: ', result.trigger.layer)
console.log('Trigger position: ', result.trigger.position)
console.log('Trigger rotation: ', result.trigger.rotation)
console.log('Trigger scale: ', result.trigger.scale)
})
Trigger area layers #
Use the optional second argument of the TriggerArea
component to set the layers that will activate the trigger area.
By deault, the trigger area is activated only by the player, via the layer ColliderLayer.CL_PLAYER
. You can change this to any other collision layer by passing it as the second argument of the TriggerArea
component.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
// Trigger area
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity, ColliderLayer.CL_CUSTOM1)
Transform.create(triggerEntity, {
position: Vector3.create(8, 0, 8),
})
// Entity that will activate the trigger area
const movingEntity = engine.addEntity()
Transform.create(movingEntity, {
position: Vector3.create(8, 0, 8),
})
MeshCollider.setBox(movingEntity, ColliderLayer.CL_CUSTOM1)
Allowed values are the same as the ones for the MeshCollider
component. See
Collision layers
for more details.
ColliderLayer.CL_PHYSICS
ColliderLayer.CL_POINTER
ColliderLayer.CL_CUSTOM1
through toCL_CUSTOM8
ColliderLayer.CL_NONE
💡 Tip: The layersCL_CUSTOM1
through toCL_CUSTOM8
don’t have any special behavior on their own, you can use them for whatever suits your scene best.
You can also set up a trigger area to detect multiple layers at once.
import { engine } from '@dcl/sdk/ecs'
import { TriggerArea } from '@dcl/sdk/triggers'
const triggerEntity = engine.addEntity()
TriggerArea.setBox(triggerEntity, ColliderLayer.CL_CUSTOM1 | ColliderLayer.CL_CUSTOM2)
Transform.create(triggerEntity, {
position: Vector3.create(8, 0, 8),
})
This will activate the trigger area when any entity with the layers CL_CUSTOM1
or CL_CUSTOM2
enters the trigger area.