> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/click-events.md).

# Eventos de Clique

Saiba como lidar com cliques de usuário na sua scene.

Uma cena do Decentraland pode detectar ações de entrada de todos os botões usados para controlar o avatar do jogador. Isso inclui cliques de ponteiro, vários botões de ação e as teclas usadas para mover o avatar. Eventos de botão podem vir de um mouse e teclado no cliente desktop, dos controles na tela no [aplicativo móvel](/creator/content-creator-pt/criar-para-mobile/cliente-movel/overview.md), de um controle de VR ou de outros dispositivos de entrada — todos são interpretados da mesma forma pelo SDK.

Você pode detectar ações de entrada contra uma Entity. Isso envolve pressionar um botão enquanto o cursor do jogador está apontando para o collider dessa Entity. Você também pode detectar *global* evento de entrada, que envolve pressionar/ativar a entrada a qualquer momento, sem considerar para onde o ponteiro está apontando.

{% hint style="warning" %}
**📔 Observação**: Entities devem ter um [collider](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md) para responder a ações de entrada. `MeshRenderer` models também devem receber um `MeshCollider` component. Modelos de um `GltfContainer` podem ter sua própria geometria de colisão incorporada, ou podem ser configurados para usar sua geometria visível; também podem receber um `MeshCollider` component.
{% endhint %}

Há várias maneiras diferentes de lidar com ações de entrada, dependendo do caso de uso.

* [**Registrar um callback**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/register-callback.md): A maneira mais fácil de adicionar interação a uma única Entity. Escreva uma única instrução para configurar uma função de callback e o feedback de hover.
* [**baseada em System**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/system-based-events.md): Ideal para lidar com várias Entities com comportamento semelhante. Use um system para iterar sobre Entities semelhantes e consultar ações de entrada em cada uma, lidando com todas com a mesma lógica. O feedback de hover precisa ser configurado separadamente. Essa abordagem também é necessária para lidar com ações globais de entrada.
* [**Avançado**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/advanced-button-events.md): Leia os dados brutos de resposta em cada Entity, incluindo marcas de tempo e um histórico de eventos de entrada. Isso pode ser útil para definir padrões personalizados de interação.

## Use o Scene Editor no Creator Hub

A maneira mais fácil de lidar com eventos de clique em uma Entity é usar o Scene Editor. Use o no-code **On Click** ou **On Input Action** Triggers em um item para chamar ações ao clicar nele. Ou use **On Global Click**, **On Global Primary** ou **On Global Secondary** Triggers para reagir a eventos globais de botão. Veja [Torne qualquer item num smart item](/creator/content-creator-pt/scene-editor/interatividade/make-any-item-smart.md).

## Exemplo simples

Para detectar cliques em uma Entity, use `pointerEventsSystem.onPointerDown`.

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_PRIMARY, hoverText: 'Click' },
	},
	function () {
		console.log('clicked entity')
	}
)
```

Veja [**Registrar um callback**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/register-callback.md) para mais informações.

## Feedback ao passar o mouse

É importante deixar claro para os jogadores que uma Entity é interativa. Caso contrário, eles podem perder completamente a experiência que você construiu. Não é uma boa experiência clicar em todos os objetos na esperança de que um responda.

Quando você usa o [**Registrar um callback**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/register-callback.md) método, dois tipos de feedback são exibidos sempre que o jogador passa o cursor sobre o objeto:

* A borda da Entity é destacada (somente no cliente Desktop do Decentraland 2.0). O destaque é verde se a Entity estiver perto o suficiente para clicar, vermelho se a Entity estiver longe demais.
* Uma dica de hover aparece perto do cursor com texto de UI, sinalizando o que acontecerá se clicarem.

Ao usar o [**baseada em System**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/system-based-events.md) método, você pode obter os mesmos resultados adicionando um `PointerEvents` component às Entities clicáveis.

Tanto o destaque da Entity quanto a dica de hover podem ser desativados por meio de propriedades nesses métodos e components.

Você também pode implementar [dicas personalizadas avançadas](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/system-based-events.md#advanced-custom-hints), por exemplo, você poderia tocar um som, fazer a Entity mudar de cor, girar ou aumentar enquanto estiver sendo apontada etc. Seja o que for que você faça, certifique-se de que seja um sinalizador claro.

## Obstáculos

Eventos de botão lançam raios que só interagem com a primeira Entity em seu caminho que esteja inscrita na collision layer de pointer events. Isso é verdade desde que a Entity esteja dentro de seus limites de distância. Se a Entity definir limites de distância tanto para a camera quanto para o avatar, basta que qualquer um dos dois esteja perto o suficiente.

Para que uma Entity seja interceptada pelo raio de um evento de ponteiro, uma das seguintes opções:

* O modelo deve conter [malhas de colisão](/creator/content-creator-pt/modelacao-3d-e-animacoes/colliders.md).
* O `GltfContainer` deve ser configurado para usar a [geometria visível com máscaras de colisão](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md#colliders-on-3d-models).
* A Entity deve ter um [MeshCollider component](/creator/content-creator-pt/scenes-sdk7/fundamentos-de-conteudo-3d/colliders.md).

Se o collider de outra Entity estiver no caminho da Entity com a qual o jogador quer interagir, o jogador não conseguirá clicar na Entity que está atrás, a menos que a Entity não tenha collider, ou que esse collider esteja configurado para não responder à collision layer de pointer events.

```ts
// Entity clicável
const clickableEntity = engine.addEntity()
MeshRenderer.setBox(clickableEntity)
MeshCollider.setBox(clickableEntity)
Transform.create(clickableEntity, { position: Vector3.create(8, 1, 8) })

pointerEventsSystem.onPointerDown(
	{
		entity: clickableEntity,
		opts: {
			button: InputAction.IA_POINTER,
			hoverText: 'Click',
		},
	},
	function () {
		console.log('clicked entity')
		const t = Transform.getMutable(clickableEntity)
		t.scale.y += 0.2
	}
)

// não bloqueia cliques
const nonBlocker = engine.addEntity()
MeshRenderer.setBox(nonBlocker)
MeshCollider.setBox(nonBlocker, ColliderLayer.CL_PHYSICS)
Transform.create(nonBlocker, { position: Vector3.create(10, 1, 8) })

// bloqueador de cliques
const blocker = engine.addEntity()
MeshRenderer.setBox(blocker)
MeshCollider.setBox(blocker, ColliderLayer.CL_POINTER)
Transform.create(blocker, { position: Vector3.create(8, 1, 10) })
```

{% hint style="warning" %}
**📔 Observação**: Para que uma Entity não apenas intercepte um evento de ponteiro, mas também retorne dados, ela também precisa ter um `PointerEvents` component. O `pointerEventsSystem` helpers também cuidam desse requisito.
{% endhint %}

## Botões do Pointer

As seguintes entradas podem ser tratadas por qualquer uma das abordagens para detectar eventos de entrada.

* `InputAction.IA_POINTER`: **botão esquerdo do mouse** em um computador, **botão de interação** no mobile.
* `InputAction.IA_PRIMARY`: **E** tecla em um computador, **Botão E** no mobile.
* `InputAction.IA_SECONDARY`: **F** tecla em um computador, **Botão F** no mobile.
* `InputAction.IA_ACTION_3`: **1** tecla em um computador, **botão 1** no mobile. *Não é facilmente acessível no mobile — não recomendado para interação no mobile.*
* `InputAction.IA_ACTION_4`: **2** tecla em um computador, **botão 2** no mobile. *Não é facilmente acessível no mobile — não recomendado para interação no mobile.*
* `InputAction.IA_ACTION_5`: **3** tecla em um computador, **botão 3** no mobile. *Não é facilmente acessível no mobile — não recomendado para interação no mobile.*
* `InputAction.IA_ACTION_6`: **4** tecla em um computador, **botão 4** no mobile. *Não é facilmente acessível no mobile — não recomendado para interação no mobile.*
* `InputAction.IA_JUMP`: **Espaço** tecla em um computador, **botão de pulo** no mobile.
* `InputAction.IA_FORWARD`: **W** tecla em um computador.
* `InputAction.IA_LEFT`: **Um** tecla em um computador.
* `InputAction.IA_RIGHT`: **D** tecla em um computador.
* `InputAction.IA_BACKWARD`: **S** tecla em um computador.
* `InputAction.IA_WALK`: **Controlar** tecla em um computador.
* `InputAction.IA_MODIFIER`: **Shift** tecla em um computador.

Cada `InputAction` é abstraído da entrada literal no teclado para que possa ser mapeado para diferentes entradas dependendo do dispositivo. Pelo mesmo motivo, nem todos os botões do teclado podem ser rastreados para eventos de botão, apenas os botões usados para movimento e interação. Essa limitação intencional garante que o conteúdo seja compatível entre desktop, o [cliente móvel](/creator/content-creator-pt/criar-para-mobile/cliente-movel/overview.md), e futuros dispositivos como controles de VR e outros controles de jogo.

{% hint style="warning" %}
**📱 Mobile**: No [cliente móvel](/creator/content-creator-pt/criar-para-mobile/cliente-movel/overview.md), todas as ações de entrada estão disponíveis, mas `IA_ACTION_3`–`IA_ACTION_6` (a `1`/`2`/`3`/`4` botões) ficam escondidos atrás de um menu secundário e não são facilmente acessíveis durante o gameplay. Ao projetar para mobile, prefira `IA_POINTER` (botão de interação), `IA_PRIMARY` (botão E), e `IA_SECONDARY` (botão F) para suas ações principais. Veja [Input no mobile](/creator/content-creator-pt/criar-para-mobile/desenvolver/input-on-mobile.md).
{% endhint %}

## Tipos de eventos de ponteiro

Cada entrada pode produzir os seguintes tipos de eventos de ponteiro. Cada um dos seguintes é um valor em `PointerEventType` .

* `PET_DOWN`: O jogador pressiona um botão específico enquanto o cursor está apontando para o collider da Entity.
* `PET_UP`: O jogador solta um botão específico enquanto o cursor está apontando para o collider da Entity.
* `PET_HOVER_ENTER`: O cursor do jogador começa a apontar para o collider da Entity.
* `PET_HOVER_LEAVE`: O cursor do jogador deixa de apontar para o collider da Entity.
* `PET_PROXIMITY_ENTER`: O jogador entra no alcance de proximidade da Entity, independentemente de para onde está olhando.
* `PET_PROXIMITY_LEAVE`: O jogador sai do alcance de proximidade da Entity.

Veja [**Proximity Events**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/proximity-events.md) para ver como usar interações baseadas em proximidade.

## Dados de uma ação de entrada

Todas as ações de entrada incluem dados sobre o evento, incluindo coisas como o botão que foi ativado e para onde o ponteiro estava apontando naquele momento.

As seguintes informações podem ser obtidas de qualquer evento de entrada:

* `analógico`: Número opcional, presente apenas em eventos de um input analógico (como um joystick), que guarda o valor analógico do input.
* `button`: Que id do botão foi pressionado. O número corresponde ao `InputAction` enum, que lista todos os botões disponíveis.
* `state`: Tipo de evento de pointer, do enum `PointerEventType`. *0* refere-se a `PointerEventType.PET_UP`, *1* como `PointerEventType.PET_DOWN`, *2* como `PointerEventType.PET_HOVER_ENTER`, *3* como `PointerEventType.PET_HOVER_LEAVE`, *4* como `PointerEventType.PET_PROXIMITY_ENTER`, *5* como `PointerEventType.PET_PROXIMITY_LEAVE`
* `timestamp`: Um [timestamp de Lamport](https://en.wikipedia.org/wiki/Lamport_timestamp) para identificar cada evento de botão.

  > Nota: este timestamp não é numerado com base na hora atual. Pense nele como um contador que começa em 0 e é incrementado em 1 para cada evento.
* `impacto`: Um objeto que contém os seguintes dados sobre o evento de impacto:
  * `entityId`: Número de identificação da Entity que foi atingida pelo raio.
  * `meshName`: *String* com o nome interno da malha específica no modelo 3D que foi atingida. Isso é útil quando um modelo 3D é composto por várias malhas.
  * `globalOrigin`: *Vector3* para a posição de onde o raio se origina (relativa à scene)
  * `direção`: *Vector3* com o vetor de direção do ray, em coordenadas globais
  * `position`: *Vector3* para a posição onde o raio se intersectou com a Entity atingida (relativa à scene)
  * `length`: Comprimento do raio desde sua origem até a posição em que ocorreu o impacto contra a Entity.
  * `normalHit`: *Vector3* com um vetor de direção normalizado, que descreve o ângulo da normal do impacto no espaço global.

Esses dados são acessados de maneiras diferentes, dependendo da abordagem que você estiver usando para lidar com ações de entrada.

Usando a [**Registrar um callback**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/register-callback.md) abordagem, o primeiro parâmetro passado para a função de callback contém toda essa estrutura de dados.

```ts
pointerEventsSystem.onPointerDown({ entity: myEntity }, function (cmd) {
	console.log(cmd.hit?.entityId)
})
```

Usando a [**baseada em System**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/system-based-events.md) abordagem, use `inputSystem.getInputCommand()` para obter esses dados.

```ts
engine.addSystem(() => {
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)
	if (cmd) {
		console.log(cmd.hit?.entityId)
	}
})
```

{% hint style="warning" %}
**📔 Observação**: Para que uma Entity não apenas intercepte um evento de ponteiro, mas também retorne dados, ela também precisa ter um `PointerEvents` component. O `pointerEventsSystem` helpers também cuidam desse requisito.
{% endhint %}

Usando a [**Avançado**](/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/advanced-button-events.md) abordagem, o `PointerEventsResult` contém uma lista com um histórico recente de todos os eventos de ponteiro contra essa Entity.

```ts
engine.addSystem(() => {
	for (const [entity] of engine.getEntitiesWith(PointerEventsResult)) {
		const pointerEvents = PointerEventsResult.get(entity)

		for (const event of pointerEvents) {
			console.log(event.hit?.entityId)
		}
	}
})
```

## Bloquear ou desbloquear o cursor

{% hint style="info" %}
**💡 Nota**: `PointerLock` é um conceito do cliente desktop (cursor do mouse bloqueado vs. desbloqueado). Não tem efeito no [aplicativo móvel](/creator/content-creator-pt/criar-para-mobile/cliente-movel/overview.md), onde a entrada é baseada em toque.
{% endhint %}

Os jogadores no cliente desktop do Decentraland podem alternar entre dois modos distintos de interação com o cursor:

* Cursor bloqueado: mover o mouse desloca a câmera e os eventos de clique ocorrem na mira no centro da tela
* Cursor desbloqueado: o cursor pode se mover livremente independentemente da câmera, e os jogadores podem clicar em qualquer lugar da tela para interagir com o espaço 3D ou com a UI

Esses modos de interação são ideais para diferentes tipos de mecânicas de jogo, e você pode querer fazer com que os jogadores adotem um ou outro dependendo do que melhor se adapta à sua Scene. Você também pode querer garantir momentaneamente que o cursor do jogador esteja desbloqueado para permitir que ele interaja com uma UI; isso é especialmente útil para novos jogadores que não estão familiarizados com esse controle.

Para mudar o estado do cursor do jogador, use o `PointerLock` component no `engine.CameraEntity` entity.

```ts
import {PointerLock} from '@dcl/sdk/ecs'
    
PointerLock.createOrReplace(engine.CameraEntity, {isPointerLocked: false})
```

{% hint style="warning" %}
**📔 Observação**: O engine fornece um `PointerLock` component no `engine.CameraEntity` por padrão. Use `createOrReplace()` ou `getMutable()` em vez de `create()`, que lança um erro se o component já existir.
{% endhint %}

Você também pode consultar o estado do cursor do jogador lendo o `PointerLock` estado do component.

```ts
import {PointerLock} from '@dcl/sdk/ecs'

const isPointerLocked = PointerLock.getOrNull(engine.CameraEntity)?.isPointerLocked
```

Use o `.onChange` função para reagir a mudanças no estado do ponteiro. O exemplo a seguir impõe que o cursor esteja sempre desbloqueado.

```ts
import {PointerLock} from '@dcl/sdk/ecs'

export function main() {

    PointerLock.createOrReplace(engine.CameraEntity, {isPointerLocked: false});

    PointerLock.onChange(engine.CameraEntity, (pointerLock) => {
		    if (!pointerLock) return
		    if(pointerLock.isPointerLocked){
			    PointerLock.getMutable(engine.CameraEntity).isPointerLocked = false
		   }
	})
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/interatividade/eventos-de-botao/click-events.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
