> 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-es/scenes-sdk7/interactividad/eventos-de-button/register-callback.md).

# Registrar callback

Aprende cómo manejar los clics de los usuarios en tu escena.

La forma más sencilla de manejar eventos de botones es registrar una función de callback para una Entity concreta. Cada vez que se interactúe con esa Entity usando un botón específico, se llamará a la función de callback.

Si necesitas añadir el mismo comportamiento a múltiples Entities similares, considera usar el [basado en System](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/system-based-events.md) enfoque en lugar de añadir callbacks a cada Entity. El enfoque basado en System puede ser más eficiente a medida que iteras sobre una lista de Entities similares.

El enfoque Register callback es especialmente útil si quieres describir un comportamiento que afecta a una sola Entity, ya que es más directo.

{% hint style="warning" %}
**📔 Nota**:\
Para que una Entity sea interactiva, debe **deben** tener un [collider](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md). Consulta [obstáculos](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#obstacles) para más detalles.
{% endhint %}

## Pulsación del puntero

Usa `pointerEventsSystem.onPointerDown()` para detectar pulsaciones de un botón específico.

Esta instrucción requiere dos parámetros:

* `datos`: Un objeto que contiene lo siguiente:
  * `entidad`: La Entity que se manejará
  * `opts`: Un objeto con datos adicionales opcionales:
    * `button`: Qué botón escuchar. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para ver las opciones compatibles. Si no se especifica ningún botón, entonces se escuchan todos los botones, incluidos botones de movimiento como avanzar y saltar.
    * `maxDistance`: La distancia máxima entre la Entity y el **avatar**, en metros. 10 por defecto. Consulta [Límites de distancia](#distance-limits).
    * `maxCameraDistance`: La distancia máxima entre la Entity y la **cámara activa**, en metros. No se establece por defecto. Consulta [Límites de distancia](#distance-limits).
    * `hoverText`: Qué cadena mostrar en la sugerencia visual al pasar el cursor. "Interactuar" por defecto.
    * `showFeedback`: Si es falso, oculta tanto la sugerencia al pasar el cursor como el resaltado del borde para esta Entity. *true* por defecto.
    * `showHighlight`: Si es verdadero, los jugadores verán el resaltado del borde al pasar el cursor sobre la Entity. *true* por defecto. Este valor solo se considera si `showFeedback` es *true*.
* `cb`: Una función de callback que se ejecuta cada vez que ocurre un evento de button down mientras se apunta a la Entity

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

El comando anterior deja registrada la función de callback, y se llamará cada vez que ocurra el evento de botón relacionado. Ten en cuenta que la callback debe ser una función síncrona; `async` las funciones no son compatibles aquí y provocan un error.

{% hint style="warning" %}
**📔 Nota**:\
Solo una `pointerEventsSystem.onPointerDown` se puede registrar por Entity. Una vez agregado, seguirá escuchando eventos hasta que se elimine el listener. No lo ejecutes de forma recurrente dentro de un System, ya que eso seguiría reescribiendo el comportamiento del evento del puntero.
{% endhint %}

## Feedback al pasar el cursor

Es muy importante dar a los jugadores algún tipo de indicación de que se puede interactuar con una Entity.

Al registrar una acción de entrada con el `EventsSystem`, los jugadores verán por defecto:

* Un resaltado del borde en la Entity
* Una sugerencia al pasar el cursor cerca del puntero con un icono del botón que deben pulsar y una cadena que dice "Interactuar".

Estos elementos se pueden activar o desactivar y personalizar.

La retroalimentación al pasar el cursor en la UI muestra un icono diferente según la entrada que selecciones en el `button` campo. En PC, muestra un icono con una `E` para `InputAction.IA_PRIMARY`, una `F` para `InputAction.IA_SECONDARY`, y un ratón para `InputAction.IA_POINTER`.

Cambia la cadena cambiando el `hoverText` valor. Mantén esta cadena corta para que sea rápida de leer y no resulte demasiado intrusiva en la pantalla.

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_PRIMARY, hoverText: 'Abrir puerta' },
	},
	function () {
		// abrir la puerta
	}
)
```

Para ocultar la sugerencia al pasar el cursor, pero dejar el resaltado del borde, establece el valor de `hoverText` a "".

```ts
pointerEventsSystem.onPointerDown(
  {entity: myEntity, opts: { button: InputAction.IA_PRIMARY, hoverText: ''}},
  function () {
    console.log("se hizo clic en el elemento interactivo sorpresa")
  }
)
```

Para ocultar el resaltado del borde pero dejar la sugerencia al pasar el cursor, establece `showHighlight` en *false*.

```ts
pointerEventsSystem.onPointerDown(
	{
		entity: myEntity,
		opts: {
			button: InputAction.IA_PRIMARY,
			hoverText: 'Abrir puerta',
			showHighlight: false,
		},
	},
	function () {
		console.log('se abrió la puerta secreta')
	}
)
```

Para ocultar tanto la sugerencia al pasar el cursor como el resaltado del borde, establece `showFeedback` en *false*. Al hacer esto, el cursor no muestra ningún icono, texto ni resaltado del borde.

```ts
pointerEventsSystem.onPointerDown(
  {entity: myEntity, opts: { button: InputAction.IA_PRIMARY, showFeedback: false}},
  function () {
    console.log("se abrió la puerta secreta")
  }
)
```

### Cambiar la retroalimentación existente

Al registrar una acción de entrada con el `EventsSystem`, esto está creando un `PointerEvents` component y añadiéndolo a la Entity interactiva detrás de escena. Este component maneja el comportamiento de la sugerencia de la UI al pasar el cursor. Para cambiar el comportamiento de la retroalimentación al pasar el cursor, modifica este component. Consulta [Mostrar retroalimentación](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/system-based-events.md#show-feedback) para obtener más información sobre cómo tratar con este component.

```ts
const hoverFeedback = PointerEvents.getMutable(myEntity)

if (hoverFeedback.pointerEvents[0]?.eventInfo) {
	hoverFeedback.pointerEvents[0].eventInfo.hoverText = 'Cerrar puerta'
}
```

## Límites de distancia

Por defecto, un jugador solo puede interactuar con una Entity cuando su **avatar** está a menos de 10 metros de ella. Si el jugador está demasiado lejos, el efecto de resaltado de la Entity se vuelve rojo en lugar de verde, y los eventos del puntero no se activan.

Usa `maxDistance` para cambiar ese rango:

```ts
// Solo se puede hacer clic cuando el avatar del jugador está a menos de 5 metros
pointerEventsSystem.onPointerDown(
	{ entity: myEntity, opts: { maxDistance: 5 } },
	function () {
		console.log('Entity pulsada')
	}
)
```

### Limitar por distancia de la cámara

`maxCameraDistance` se mide desde la **cámara actualmente activa** en lugar del avatar. Esto es útil cuando tu Scene usa una [Virtual Camera](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/camera.md#using-virtual-cameras) colocada lejos del jugador, y quieres que la Entity se pueda pulsar en función de lo que la cámara puede ver.

```ts
// Solo se puede hacer clic cuando la cámara activa está a menos de 15 metros
pointerEventsSystem.onPointerDown(
	{ entity: myEntity, opts: { maxCameraDistance: 15 } },
	function () {
		console.log('Entity pulsada')
	}
)
```

### Cómo se combinan los dos límites

Las dos opciones son comprobaciones independientes. Cuáles se ejecutan depende de cuáles establezcas:

| Lo que estableces        | Lo que necesita el jugador                                  |
| ------------------------ | ----------------------------------------------------------- |
| Ninguno                  | Avatar a menos de 10 metros (el valor predeterminado)       |
| `maxDistance` solo       | Avatar a menos de `maxDistance`                             |
| `maxCameraDistance` solo | Cámara a menos de `maxCameraDistance`                       |
| Ambos                    | **Cualquiera** que una comprobación se supere es suficiente |

Establecer ambos es una forma de decir "lo suficientemente cerca como para acercarte caminando, **o** lo suficientemente cerca como para verlo con claridad":

```ts
// Se puede pulsar cuando el avatar está a menos de 3 metros O la cámara está a menos de 20 metros
pointerEventsSystem.onPointerDown(
	{ entity: myEntity, opts: { maxDistance: 3, maxCameraDistance: 20 } },
	function () {
		console.log('Entity pulsada')
	}
)
```

{% hint style="warning" %}
**📔 Nota**: `maxCameraDistance` requiere `@dcl/sdk` versión 7.28.0 o posterior. El soporte para ello ya está disponible en el Explorer basado en Bevy. Si tu Scene debe comportarse de forma idéntica en todos los clientes hoy, confía en `maxDistance` y considera `maxCameraDistance` como una mejora.
{% endhint %}

### maxPlayerDistance está obsoleto

`maxPlayerDistance` es un alias obsoleto de `maxDistance`: ambos miden la distancia desde el avatar. Usa `maxDistance` en nuevas Scenes.

Si una Scene establece ambos, el **mayor** de los dos se usa como límite de distancia del avatar.

## Soltar el puntero

Usa `pointerEventsSystem.onPointerUp` para registrar una función de callback que se llama cuando el jugador indicado suelta el botón mientras apunta a la Entity.

```ts
pointerEventsSystem.onPointerUp(
	{
		entity: myEntity,
		opts: { button: InputAction.IA_PRIMARY, hoverText: 'Botón soltado' },
	},
	function () {
		console.log('botón soltado')
	}
)
```

Esta instrucción requiere dos parámetros:

* `datos`: Un objeto que contiene lo siguiente:
  * `entidad`: La Entity que se manejará
  * `opts`: Un objeto con datos adicionales opcionales:
    * `button`: Qué botón escuchar. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para ver las opciones compatibles. Si no se especifica ningún botón, entonces se escuchan todos los botones, incluidos botones de movimiento como avanzar y saltar.
    * `hoverText`: Qué cadena mostrar en la sugerencia visual al pasar el cursor. "Interactuar" por defecto.
    * `showFeedback`: Si es falso, oculta la sugerencia al pasar el cursor para esta Entity. *true* por defecto.
    * `maxDistance`: Qué tan lejos puede estar el avatar del jugador de la Entity y seguir interactuando con ella, en metros. 10 por defecto. Si el jugador está demasiado lejos, no habrá retroalimentación al pasar el cursor y los eventos del puntero no funcionarán. Consulta [Límites de distancia](#distance-limits).
* `cb`: Una función de callback que se ejecuta cada vez que ocurre un evento de button up mientras se apunta a la Entity.

Una misma Entity puede tener dos callbacks diferentes registrados, uno para `pointerEventsSystem.onPointerDown` y otro para `pointerEventsSystem.onPointerUp`. La Entity solo puede registrar un callback de cada tipo, [Manejar múltiples botones](#handle-multiple-buttons) para detectar distintos botones en un mismo callback.

{% hint style="warning" %}
**📔 Nota**: La retroalimentación al pasar el cursor para un evento de button up solo se muestra cuando el botón está pulsado en ese momento. Si el jugador apunta a la Entity sin mantener pulsado el botón, no verá ninguna retroalimentación, o la retroalimentación del evento de button down, si la hay.
{% endhint %}

## Entrada y salida al pasar el cursor

Usa `pointerEventsSystem.onPointerHoverEnter` para ejecutar un callback cuando el cursor del jugador comienza a apuntar a una Entity, y `pointerEventsSystem.onPointerHoverLeave` cuando el cursor deja de apuntar a ella.

```ts
pointerEventsSystem.onPointerHoverEnter(
    {
        entity: myEntity,
        opts: { button: InputAction.IA_POINTER },
    },
    function () {
        console.log('El cursor comenzó a pasar sobre la Entity')
    }
)

pointerEventsSystem.onPointerHoverLeave(
    {
        entity: myEntity,
        opts: { button: InputAction.IA_POINTER },
    },
    function () {
        console.log('El cursor dejó de pasar sobre la Entity')
    }
)
```

Estos callbacks son útiles para efectos personalizados al pasar el cursor, como reproducir un sonido o animar la Entity cuando el jugador apunta hacia ella.

## Eliminar callbacks

Para eliminar una función de callback, usa la función remove correspondiente:

```ts
pointerEventsSystem.removeOnPointerDown(myEntity)
pointerEventsSystem.removeOnPointerUp(myEntity)
pointerEventsSystem.removeOnPointerHoverEnter(myEntity)
pointerEventsSystem.removeOnPointerHoverLeave(myEntity)
```

Una vez eliminado, la retroalimentación al pasar el cursor en la Entity ya no debería mostrarse, y la Entity ya no debería ser interactiva.

Cada función remove elimina solo la entrada que añadió su función register correspondiente. Registrar y eliminar repetidamente el mismo callback no deja entradas obsoletas en la Entity.

## Interacciones de proximidad

Para interacciones que se activan según la proximidad del jugador en lugar de la puntería del cursor, consulta [**Eventos de proximidad**](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/proximity-events.md). El `pointerEventsSystem` incluye helpers equivalentes (`onProximityDown`, `onProximityUp`, `onProximityEnter`, y `onProximityLeave`) que siguen el mismo patrón que las funciones descritas en esta página.

Una Entity puede tener tanto un handler de cursor como un handler de proximidad para el mismo tipo de evento. Ambos callbacks se ejecutan, cada uno cuando se cumple su propia condición.

### Datos de la acción de entrada

Obtén datos de una acción de entrada, como el botón que se pulsó, la Entity alcanzada, la dirección y longitud del ray, etc. Consulta ([Ver documentación](https://github.com/decentraland/docs/tree/main/README.md)) para una descripción de todos los datos disponibles.

Para obtener estos datos, pasa un parámetro a la función de callback. Este parámetro contiene la estructura de datos completa con información sobre el evento de entrada.

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

### Manejar múltiples botones

No puedes registrar más de un `onPointerDown` en una sola Entity. Idealmente deberías usar el [basado en System](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/system-based-events.md) enfoque, ya que esto te permite manejar tantos inputs diferentes como desees y mostrar una sugerencia de retroalimentación de UI al pasar el cursor para cada botón.

Como alternativa, puedes usar el enfoque Register callback y establecer el `button` campo como `InputAction.IA_ANY`.

```ts
pointerEventsSystem.onPointerDown(
  {entity: myEntity, opts: { button: InputAction.IA_ANY}},
  function (cmd) {
      if(cmd.button === InputAction.IA_POINTER){
        // hacer X
      } else if (cmd.button === InputAction.IA_PRIMARY){
        // hacer Y
      }
  }
)
```

Este enfoque no es ideal, ya que la sugerencia al pasar el cursor muestra una sola cadena y no especifica qué acción activar. Ten en cuenta que esto hará que la función de callback se ejecute para cada acción de entrada, incluidas las teclas de movimiento, así que debes filtrar solo las acciones que te interesan.


---

# 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-es/scenes-sdk7/interactividad/eventos-de-button/register-callback.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.
