# Áreas de Trigger

As áreas de Trigger permitem reagir ao evento de um jogador entrando ou saindo de uma área, ou de qualquer outra entidade entrando ou saindo de uma área. Esta é uma ferramenta fundamental para criar cenas interativas. Use-as para coisas como abrir uma porta quando o jogador se aproxima, ou para marcar um ponto quando uma bola entra em um gol.

## Usando áreas de Trigger

Para usar áreas de Trigger você precisa adicionar um `TriggerArea` componente a uma entidade, depois usar um `triggerAreaEventsSystem` para reagir aos eventos.

```ts
import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

// criar entidade
const triggerEntity = engine.addEntity()

// definir Transform
Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8)
  })

// Área de Trigger
TriggerArea.setBox(triggerEntity)

// Evento quando a área de trigger é ativada
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
  if (result.trigger?.entity !== engine.PlayerEntity) return;
  console.log('Player entered trigger area!')
})
```

Por padrão, o `TriggerArea` componente reage ao evento de *qualquer* jogador entrando na área. O código acima adiciona `if (result.trigger?.entity !== engine.PlayerEntity) return` para verificar que a entidade que causou o evento é o jogador atual, e não o avatar de outra pessoa

## Formas das áreas de Trigger

As áreas de Trigger podem ser uma caixa ou uma esfera.

```ts
import { engine, Transform, TriggerArea } from '@dcl/sdk/ecs'

// Caixa
TriggerArea.setBox(triggerEntity)

// Esfera
TriggerArea.setSphere(triggerEntity)
```

{% hint style="info" %}
**💡 Dica**: A esfera é a forma mais fácil de calcular para o engine, pois é obtida verificando a distância do centro da esfera. Em caso de dúvida, use uma esfera.
{% endhint %}

Para alterar o tamanho da área de trigger, você pode usar o `scale` propriedade do `Transform` componente na entidade que contém o `TriggerArea`.

```ts
import { engine, Transform, TriggerArea } from '@dcl/sdk/ecs'

const triggerEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity)

Transform.create(triggerEntity, {
  scale: Vector3.create(4, 2, 4),
})
```

### Depuração

Para depurar sua cena e ver a área coberta pela área de trigger, você pode adicionar um `MeshShape` componente à entidade com a área de trigger, e definir a forma para aquela que você quer depurar. As dimensões da malha padrão corresponderão às dimensões da área de trigger.

```ts
import { engine, Transform, TriggerArea } from '@dcl/sdk/ecs'

const triggerEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity)

MeshRenderer.setBox(triggerEntity)

Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8),
})
```

## Eventos da área de Trigger

Você pode usar o `triggerAreaEventsSystem` para reagir aos diferentes eventos de uma área de trigger:

* `onTriggerEnter`: Acionado quando uma entidade entra na área de trigger.
* `onTriggerExit`: Acionado quando uma entidade sai da área de trigger.
* `onTriggerStay`: Acionado enquanto uma entidade está na área de trigger, a cada frame.

```ts
import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

const triggerEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity)

// Ao entrar
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
  console.log('Player entered trigger area!')
})

// Ao sair
triggerAreaEventsSystem.onTriggerExit(triggerEntity, function(result) {
  console.log('Player exited trigger area!')
})

// Enquanto estiver
triggerAreaEventsSystem.onTriggerStay(triggerEntity, function(result) {
  console.log('Player is in trigger area!')
})
```

## Respostas a eventos de Trigger

Quando um evento de área de trigger é acionado, você pode usar o `result` parâmetro para obter informações tanto sobre a entidade que foi acionada quanto sobre a entidade que acionou o evento.

As seguintes propriedades estão disponíveis no `result` parâmetro:

* `triggeredEntity`: O ID da entidade que foi acionada (esta é a entidade que possui a área de trigger)
* `triggeredEntityPosition`: A posição da entidade que foi acionada
* `triggeredEntityRotation`: A rotação da entidade que foi acionada
* `eventType`: O tipo de evento de trigger (ENTER, EXIT, STAY)
* `timestamp`: O timestamp do evento de trigger
* `trigger`: Um objeto com os seguintes campos:
  * `entity`: O ID da entidade que acionou o trigger (a entidade que entrou na área de trigger)
  * `layer`: A camada de colisão da entidade que acionou o trigger
  * `position`: A posição da entidade que acionou o trigger
  * `rotation`: A rotação da entidade que acionou o trigger
  * `scale`: A escala da entidade que acionou o trigger

```ts
import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

// Área de Trigger
const triggeredEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity)

Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8),
})

// Entidade que acionará a área de trigger
const triggerEntity = engine.addEntity()

const triggeredEntity = engine.addEntity()

Transform.create(triggeredEntity, {
  position: Vector3.create(8, 0, 8),
})

// Ao entrar
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)
})
```

## Camadas da área de Trigger

Use o segundo argumento opcional do `TriggerArea` componente para definir as camadas que ativarão a área de trigger.

Por padrão, a área de trigger é ativada apenas pela camada `ColliderLayer.CL_PLAYER`. Esta camada inclui todos os jogadores, não apenas o jogador atual mas também qualquer outro avatar que esteja sendo renderizado na cena. Se você quiser detectar apenas o jogador atual e não os outros, adicione a seguinte verificação na função de trigger `if (result.trigger?.entity !== engine.PlayerEntity) return`.

```ts
import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

// criar entidade
const triggerEntity = engine.addEntity()

// definir Transform
Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8)
  })

// Área de Trigger
TriggerArea.setBox(triggerEntity)

// Evento quando a área de trigger é ativada
triggerAreaEventsSystem.onTriggerEnter(triggerEntity, function(result) {
  if (result.trigger?.entity !== engine.PlayerEntity) return;
  console.log('Player entered trigger area!')
})
```

Você também pode alterar a camada de colisão para detectar qualquer outra entidade passando-a como segundo argumento do `TriggerArea` componente.

```ts
import { engine, Transform, TriggerArea, MeshCollider, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

// Área de Trigger
const triggerEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity, ColliderLayer.CL_CUSTOM1)

Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8),
})

// Entidade que ativará a área de trigger
const movingEntity = engine.addEntity()

Transform.create(movingEntity, {
  position: Vector3.create(8, 0, 8),
})

MeshCollider.setBox(movingEntity, ColliderLayer.CL_CUSTOM1)
```

Os valores permitidos são os mesmos dos do `MeshCollider` componente. Veja [Collision layers](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/colliders#Collision-layers) para mais detalhes.

* `ColliderLayer.CL_PHYSICS`
* `ColliderLayer.CL_POINTER`
* `ColliderLayer.CL_CUSTOM1` até `CL_CUSTOM8`
* `ColliderLayer.CL_NONE`

{% hint style="info" %}
**💡 Dica**: As camadas `CL_CUSTOM1` até `CL_CUSTOM8` não têm qualquer comportamento especial por si só, você pode usá-las para o que melhor servir à sua cena.
{% endhint %}

Você também pode configurar uma área de trigger para detectar várias camadas ao mesmo tempo.

```ts
import { engine, Transform, TriggerArea, triggerAreaEventsSystem } from '@dcl/sdk/ecs'

const triggerEntity = engine.addEntity()

TriggerArea.setBox(triggerEntity, ColliderLayer.CL_CUSTOM1 | ColliderLayer.CL_CUSTOM2)

Transform.create(triggerEntity, {
  position: Vector3.create(8, 0, 8),
})
```

Isto ativará a área de trigger quando qualquer entidade com as camadas `CL_CUSTOM1` ou `CL_CUSTOM2` entrar na área de trigger.
