> 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/system-based-events.md).

# Eventos basados en Systems

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

Si tu scene tiene múltiples entities similares que se activan todas usando la misma lógica, puedes escribir un solo system para iterar sobre todas ellas y describir ese comportamiento solo una vez. Esta también es la opción más performante y más [orientado a datos](/creator/content-creator-es/scenes-sdk7/arquitectura/data-oriented-programming.md) enfoque.

También puedes usar un system para detectar [eventos de entrada globales](#global-input-events)para que la scene reaccione cada vez que se presiona una tecla, sin tener en cuenta hacia dónde apunta el cursor del jugador.

Si lo único que quieres hacer es hacer click o pulsar un botón en una sola entity para activarla, la forma más fácil es usar el [Registrar un callback](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/register-callback.md) enfoque.

Para definir una lógica personalizada más específica, quizás quieras trabajar con los datos sin procesar y usar el [Avanzado](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/advanced-button-events.md) enfoque.

Para que una entity sea interactiva, debe 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. Esto también aplica a los eventos de click por proximidad.

## Usando un system

Comprueba los eventos de botón ejecutando una de las funciones auxiliares en el input `inputSystem` namespace en cada tick dentro de un [system](/creator/content-creator-es/scenes-sdk7/arquitectura/systems.md).

Por ejemplo, el siguiente system usa la `inputSystem.isTriggered()` función para comprobar si se hizo click en el pointer. En cada tick, comprueba si el botón fue presionado. Si `inputSystem.isTriggered()` devuelve *true*el system ejecuta cierta lógica personalizada como respuesta.

```ts
engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN)) {
		// Lógica en respuesta a la pulsación del botón
	}
})
```

Las siguientes funciones auxiliares están disponibles en el `inputSystem` namespace, y se pueden llamar de manera similar en cada tick:

* `inputSystem.isTriggered`: Devuelve true si ocurrió una input action desde el último tick.
* `inputSystem.isPressed`: Devuelve true si una input se está manteniendo pulsada actualmente. Devolverá true en cada tick hasta que el botón vuelva a soltarse.
* `inputSystem.getInputCommand`: Devuelve un objeto con datos sobre la input action.

Consulta las secciones de abajo para más detalles sobre cada una.

Al manejar eventos de botón en una entity, ofrece siempre feedback al jugador, para que el jugador sepa que se puede interactuar con una entity. Si añades un `PointerEvents` component a una entity, los jugadores verán un hint mientras pasan el cursor sobre esa entity. Consulta [Mostrar retroalimentación](#show-feedback) para aprender cómo puedes añadir hover hints en entities interactivas.

### Eventos de entrada globales

Usa `inputSystem.isTriggered` para detectar eventos de pulsación y liberación del botón en cualquiera de las entradas rastreadas por el SDK.

```ts
engine.addSystem(() => {
	si (
		inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN)
	) {
		// Lógica en respuesta a la pulsación del botón
	}
})
```

El ejemplo anterior comprueba si el botón fue presionado, sin importar dónde esté el pointer ni qué entities pueda haber en su trayectoria.

`inputSystem.isTriggered()` devuelve *true* solo si el botón indicado fue presionado en el tick actual del game loop. Si el botón no se presionó, o ya estaba presionado desde el tick anterior, devuelve *false*.

{% hint style="warning" %}
**📔 Nota**: El jugador necesita estar dentro de los límites de la scene para que se detecte el pointer event. El cursor del jugador también necesita estar bloqueado; los botones presionados con el cursor libre no se detectan.

Toda entity con la que quieras interactuar debe tener tanto un [`PointerEvents` component](#show-feedback) y una [collider](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md).
{% endhint %}

El `inputSystem.isTriggered` función toma los siguientes argumentos obligatorios:

* `InputAction`: Qué input escuchar, como un valor de `InputAction` enum. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para las opciones compatibles.
* `PointerEventType`: Qué tipo de event escuchar, como un valor de `PointerEventType` enum. Consulta [Tipos de eventos de puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#types-of-pointer-events) para las opciones compatibles.

### Activar una entity

Para detectar eventos de botón mientras apuntas a una entity concreta, pasa un tercer argumento opcional a `inputSystem.isTriggered` para especificar contra qué entity comprobar.

```ts
// Give entity a PointerEvents component
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				showFeedback: false,
			},
		},
	],
})

// crear system
engine.addSystem(() => {
	si (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_DOWN,
			myEntity
		)
	) {
		// Lógica en respuesta a la pulsación del botón en myEntity
	}
})
```

El ejemplo anterior comprueba en cada tick si una única entity codificada de forma fija fue pulsada con el botón del pointer (botón izquierdo del mouse).

El `inputSystem.isTriggered` función toma los siguientes argumentos:

* `InputAction`: Qué input escuchar, como un valor de `InputAction` enum. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para las opciones compatibles.
* `PointerEventType`: Qué tipo de event escuchar, como un valor de `PointerEventType` enum. Consulta [Tipos de eventos de puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#types-of-pointer-events) para las opciones compatibles.
* `Entity` *(opcional)*: Qué entity usar para comprobar estos events. Si no se proporciona ningún valor, comprobará pulsaciones globales del botón, sin importar hacia dónde apuntaba el cursor del jugador.

Ten en cuenta que en este ejemplo también estamos añadiendo un `PointerEvents` component a la entity con la que queremos interactuar. Este paso es necesario; sin este component la entity no será detectable por ninguna de las funciones de `inputSystem`. consulta [Mostrar feedback](#show-feedback) para más detalles sobre el `PointerEvents` componente.

{% hint style="warning" %}
**📔 Nota**: y 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 %}

Si hay múltiples entities con las que el jugador puede interactuar de la misma manera, considera usar `inputSystem.getInputCommand`. Este comando devuelve información sobre un global click command, incluido el ID de la entity; puedes usarlo para ejecutar una sola función que pueda manejarlas todas.

```ts
engine.addSystem(() => {
	const result = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN
	)
	if (result) {
		if (result.hit?.entityId === myEntity) {
			// manejar click
		}
	}
})
```

{% hint style="warning" %}
**📔 Nota**: Toda entity con la que quieras interactuar debe tener tanto un [`PointerEvents` component](#show-feedback) y una [collider](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md).
{% endhint %}

Consulta [Datos de la acción de entrada](#data-from-input-action) para más info. Este método también te ofrece datos más detallados sobre el hit del pointer event.

### Soltar botón de input

También puedes comprobar eventos de pointer up de manera muy similar, usando `PointerEventType.PET_UP`.

```ts
engine.addSystem(() => {
	si (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_UP,
			myEntity
		)
	) {
		// Lógica en respuesta a la liberación del botón mientras se apunta a myEntity
	}
})
```

{% hint style="warning" %}
**📔 Nota**: Al comprobar eventos de pointer up contra una entity específica, no tiene en cuenta hacia dónde apuntaba el cursor cuando se presionó el botón. Solo considera hacia dónde apunta el cursor cuando se suelta el botón.

Ten también en cuenta que la entity debe tener tanto un [`PointerEvents` component](#show-feedback) y una [collider](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md).
{% endhint %}

### Comprobar botones pulsados

Comprueba si un botón se está manteniendo pulsado actualmente usando `inputSystem.isPressed()` dentro de un system.

```ts
engine.addSystem(() => {
	if (inputSystem.isPressed(InputAction.IA_POINTER)) {
		// Lógica en respuesta a la pulsación mantenida del botón
	}
})
```

`inputSystem.isPressed()` devuelve *true* si el botón se está manteniendo pulsado actualmente, sin importar cuándo se presionó ni hacia dónde apunta el cursor del jugador. De lo contrario devuelve *false*.

El `inputSystem.isPressed` función toma un único argumento:

* `InputAction`: Qué input escuchar, como un valor de `InputAction` enum. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para las opciones compatibles.

### Manejar múltiples entities

Si tu scene tiene múltiples entities afectadas por pointer events de la misma manera, tiene sentido escribir un system que itere sobre todas ellas.

```ts
engine.addSystem(() => {
	const activatedEntites = engine.getEntitiesWith(PointerEvents)
	for (const [entity] of activatedEntites) {
		si (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entidad
			)
		) {
			// Lógica en respuesta a interactuar con una entity
		}
	}
})
```

Este ejemplo usa un [component query](/creator/content-creator-es/scenes-sdk7/arquitectura/querying-components.md) para iterar sobre todas las entities con un `PointerEvents` component. Luego comprueba cada una de estas entities con `inputSystem.isTriggered`, iterando sobre ellas una por una. Si se detecta una input action en cualquiera de estas entities, ejecuta lógica personalizada.

En lugar de iterar sobre *todos* las entities con un `PointerEvents` component en un solo system, quizás quieras escribir diferentes systems para manejar entities que deban comportarse de distintas maneras. El enfoque recomendado es marcar diferentes tipos de entities con [custom components](/creator/content-creator-es/scenes-sdk7/arquitectura/custom-components.md) específicos y iterar sobre ellas en systems separados.

```ts
engine.addSystem(() => {
	const activatedDoors = engine.getEntitiesWith(IsDoor, PointerEvents)
	for (const [entity] of activatedDoors) {
		si (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entidad
			)
		) {
			openDoor(entity)
		}
	}
})

engine.addSystem(() => {
	const pickedUpGems = engine.getEntitiesWith(IsGem, PointerEvents)
	for (const [entity] of pickedUpGems) {
		si (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entidad
			)
		) {
			pickUp(entity)
		}
	}
})
```

Este ejemplo tiene un system que itera sobre todas las entities que tienen un component personalizado llamado `IsDoor` y otro que itera sobre todas las entities que tienen un component personalizado llamado `isGem`. En ambos systems, comprueba cada entity que coincida para ver si fue activada con el botón del pointer.

Esta forma de organizar el código de tu scene es muy [orientado a datos](/creator/content-creator-es/scenes-sdk7/arquitectura/data-oriented-programming.md) y debería dar lugar a un uso muy eficiente de los recursos de memoria.

\## Múltiples botones en una entity

Usando helpers como `pointerEventsSystem.onPointerDown`, cada entity está limitada a tener un solo tipo de event. No puedes registrar dos button events diferentes. No tienes esa limitación cuando usas events basados en system. Por ejemplo, aquí hay una entity con la que los jugadores pueden interactuar tanto pulsando E como F, y cada una activa funcionalidades diferentes.

```ts
    engine.addSystem(() => {
        if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
            // reaccionar a E
        }
        if (inputSystem.isTriggered(InputAction.IA_SECONDARY, PointerEventType.PET_DOWN, myEntity)) {
            // reaccionar a F
        }
    })
```

## Mostrar retroalimentación

Para mostrar UI hints mientras apuntas a una entity, usa las properties del `PointerEvents` componente.

```ts
// crear entidad
const myEntity = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
			},
		},
	],
})
```

Cada vez que el cursor del jugador apunta a los colliders de esta entity, la UI mostrará un hover hint para indicar que se puede interactuar con la entity. Consulta las secciones de abajo para ver detalles sobre lo que puedes configurar.

{% hint style="warning" %}
**📔 Nota**: La `PointerEvents` component solo se encarga de mostrar el hover feedback. Para manejar los propios button events con lógica personalizada, consulta [Usando un system](#check-for-events).
{% endhint %}

El `PointerEvents` component requiere al menos una definición de pointer event. Cada definición de pointer event puede configurarse con lo siguiente:

* `eventType`: Qué tipo de event escuchar, como un valor de `PointerEventType` enum. Consulta [Tipos de eventos de puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#types-of-pointer-events) para las opciones compatibles.
* `eventInfo`: Un objeto que puede contener los siguientes campos:
  * `botón` (*requerido*): Qué input escuchar, como un valor de `InputAction` enum. Consulta [Botones del puntero](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md#pointer-buttons) para las opciones compatibles.
  * `hoverText` *(opcional)*: Qué cadena mostrar en la sugerencia visual al pasar el cursor. "Interactuar" por defecto.
  * `showFeedback` *(opcional)*: Si es falso, oculta tanto la sugerencia al pasar el cursor como el resaltado del borde para esta Entity. *true* por defecto.
  * `showHighlight` *(opcional)*: 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*.
  * `maxDistance` *(opcional)*: Qué tan lejos puede estar el **avatar** puede estar de la entity y seguir interactuando con ella, en metros. El valor predeterminado es *10 metros*. Consulta [Distancia máxima](#max-distance).
  * `maxCameraDistance` *(opcional)*: Qué tan lejos puede estar el **cámara activa** puede estar de la entity y seguir interactuando con ella, en metros. No se establece de forma predeterminada. Consulta [Distancia máxima](#max-distance).
  * `priority` *(opcional)*: Qué entity gana cuando varias se superponen. Los valores más altos tienen prioridad. *0* por defecto.

Un solo `PointerEvents` component puede contener múltiples definiciones de pointer event, que pueden detectar diferentes events para diferentes buttons. Cada entity solo puede tener *uno* `PointerEvents` component, pero este component puede incluir múltiples objetos en su `pointerEvents` array, uno por cada event al que responder.

```ts
PointerEvents.create(NPCEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Greet',
			},
		},
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Choke',
			},
		},
		{
			eventType: PointerEventType.PET_UP,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Stop Choke',
			},
		},
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_SECONDARY,
				hoverText: 'Give gem',
			},
		},
	],
})
```

Los jugadores verán múltiples etiquetas, una por cada pointer event, mostradas radialmente alrededor del cursor.

El ejemplo de abajo combina el uso de `PointerEvents` para mostrar hover hints, junto con un system que realmente maneja la acción del jugador con lógica personalizada.

```ts
// crear entidad
const myEntity = engine.addEntity()

// dar feedback hover a la entity
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Open',
			},
		},
	],
})

// manejar eventos de click en la entity
engine.addSystem(() => {
	si (
		inputSystem.isTriggered(
			InputAction.IA_POINTER,
			PointerEventType.PET_DOWN,
			myEntity
		)
	) {
		// Lógica personalizada en respuesta a una input action
	}
})
```

### Feedback al pasar el cursor

Cuando un jugador pasa el cursor sobre un item con un `PointerEvents` component, ve:

* 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 `botón` 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
// crear entidad
const chest = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Open',
			},
		},
	],
})
```

En el ejemplo anterior, el pointer event incluye un valor para `hoverText`. Este campo define la cadena que se muestra en la UI mientras el jugador apunta a la entity. De forma predeterminada, esta cadena dice *Interact*.

{% hint style="info" %}
**💡 Consejo**: La `hoverText` la cadena debe describir la acción que ocurre al interactuar. Por ejemplo `Open`, `Activar`, `Agarrar`, `Selecciona`. Estas cadenas deben ser lo más cortas posible, para evitar robar demasiada atención al jugador.
{% endhint %}

Si una entity tiene múltiples pointer events, los hover hints de cada uno se muestran radialmente alrededor del cursor.

El `hoverText` de un `.UP` pointer event solo se muestra mientras el jugador ya mantiene pulsada la tecla correspondiente y apunta a la entity.

Si una entity tiene tanto un `DOWN` pointer event y un `UP` pointer event, la hint del `DOWN` acción se muestra mientras el botón no se está pulsando. La hint cambia a la del `UP` event solo cuando el botón se pulsa y permanece pulsado.

```ts
// crear entidad
const entity = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(entity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Drag',
			},
		},
		{
			eventType: PointerEventType.PET_UP,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Drop',
			},
		},
	],
})
```

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

```ts
// crear entidad
const chest = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: '',
			},
		},
	],
})
```

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

```ts
// crear entidad
const chest = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Abrir puerta',
				showHighlight: false,
			},
		},
	],
})
```

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 de borde. También podrías simplemente eliminar el `PointerEvents` component de la entity.

```ts
// crear entidad
const chest = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				showFeedback: false,
			},
		},
	],
})
```

### Distancia máxima

Algunas entities pueden estar pensadas para ser interactivas solo a corta distancia. Si un jugador está demasiado lejos de una entity, el hover hint no se mostrará junto al cursor.

De forma predeterminada, las entities solo se pueden hacer click cuando el cursor del jugador **avatar** está dentro de *10 metros* de la entity. Puedes cambiar ese rango configurando el `maxDistance` propiedad de un pointer event.

```ts
// crear entidad
const myEntity = engine.addEntity()

// give entity a PointerEvents component
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 6,
			},
		},
	],
})

// implement a system to handle the pointer event
engine.addSystem(() => {
	// fetch data about the pointer event
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// check if the click was close enough
	if (cmd && cmd.hit && cmd.hit.length < 6) {
		// hacer algo
	}
})
```

El ejemplo anterior establece la distancia máxima para los hover hints en *6 metros*. Asegúrate de que la lógica para manejar las input actions también siga las mismas reglas. Consulta [Datos de la acción de entrada](#data-from-input-action) para saber cómo obtener la distancia de una input action.

`maxDistance` se mide desde el **avatar**del jugador, por lo que se comporta igual en primera y tercera persona.

Para limitar la interacción según qué tan lejos esté el **cámara activa** está en su lugar, usa `maxCameraDistance`. Establecer ambos significa que basta con que cualquiera de las comprobaciones se cumpla. Consulta [Límites de distancia](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/register-callback.md#distance-limits) para ver el conjunto completo de reglas.

{% hint style="warning" %}
**📔 Nota**: `maxPlayerDistance` es un alias obsoleto de `maxDistance`. Ambos miden la distancia desde el avatar, así que usa `maxDistance` en nuevas Scenes.
{% endhint %}

## Sugerencias personalizadas avanzadas

El `PointerEvents` El component añade fácilmente UI hints cuando el cursor del jugador empieza a pasar sobre una entity. Por lo general, es bueno que las hints se comporten de forma consistente con lo que los jugadores están acostumbrados a ver en otras scenes de Decentraland. Sin embargo, en algunos casos quizás quieras indicar que algo es interactivo de una forma personalizada. Por ejemplo, podrías reproducir un sonido sutil cuando el jugador empiece a pasar el cursor sobre la entity. También podrías mostrar un resaltado brillante alrededor de la entity mientras se pasa sobre ella, y ocultarlo cuando ya no se pase sobre ella. También podría usarse para mecánicas de gameplay específicas.

Usa el `inputSystem.isTriggered()` función junto con los `PointerEventType.PET_HOVER_ENTER` y `PointerEventType.PET_HOVER_LEAVE` events para llevar a cabo comportamientos personalizados cada vez que el cursor del jugador empieza a apuntar al collider de la entity, y cada vez que el cursor deja de apuntar a él.

El ejemplo de abajo agranda las entities a un tamaño de *1.5* cuando el cursor empieza a apuntar a su collider, y las vuelve a un tamaño de *1* cuando el cursor se aleja de ellas.

```ts
engine.addSystem(() => {
	const meshEntities = engine.getEntitiesWith(MeshRenderer)
	for (const [entity] of meshEntities) {
		si (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_HOVER_ENTER,
				entidad
			)
		) {
			Transform.getMutable(entity).scale = Vector3.create(1.5, 1.5, 1.5)
		}

		si (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_HOVER_LEAVE,
				entidad
			)
		) {
			Transform.getMutable(entity).scale = Vector3.create(1, 1, 1)
		}
	}
})
```

{% hint style="warning" %}
**📔 Nota**: Toda entity con la que quieras interactuar debe tener tanto un [`PointerEvents` component](#show-feedback) y una [collider](/creator/content-creator-es/scenes-sdk7/fundamentos-del-contenido-3d/colliders.md).
{% endhint %}

## Eventos de proximidad

Comprueba pulsaciones de botones por proximidad sin importar hacia dónde apunta el cursor usando `PET_DOWN` en una entity que usa `InteractionType.PROXIMITY`. Configura el `interactionType` campo en la definición del pointer event, junto a `eventInfo`, para marcar el event como basado en proximidad.

Consulta [**Eventos de proximidad**](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/proximity-events.md) para más detalles, incluidas las funciones auxiliares disponibles.

```ts
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_PRIMARY,
				hoverText: 'Press E',
				maxDistance: 5
			},
			interactionType: InteractionType.PROXIMITY,
		},
	],
})

engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
		console.log('Player pressed button near entity')
	}
})
```

Con helpers como `pointerEventsSystem.onProximityDown`una entity puede tener a la vez un manejador del cursor y un manejador de proximidad, y ambos callbacks se ejecutan. Lo que no puede hacer es registrar dos botones distintos para el mismo manejador. Los events basados en system no tienen ninguna de esas limitaciones: defines una entrada por comportamiento. Por ejemplo, aquí hay una entity que puede interactuarse tanto apuntándole con el cursor y pulsando E, como acercándote a ella y pulsando E sin apuntarle con el cursor.

```ts
	PointerEvents.create(myEntity, {
        pointerEvents: [
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_POINTER,
                    hoverText: 'Click',
                    maxDistance: 15,
                },
                interactionType: InteractionType.CURSOR,
            },
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_PRIMARY,
                    hoverText: 'Press E',
                    maxDistance: 15,
                },
                interactionType: InteractionType.PROXIMITY,
            },
        ],
    })
    
    engine.addSystem(() => {
        if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_DOWN, myEntity)) {
            console.log('Player clicked at entity')
        }
        if (inputSystem.isTriggered(InputAction.IA_PRIMARY, PointerEventType.PET_DOWN, myEntity)) {
            console.log('Player pressed button near entity')
        }
    })
```

También puedes usar `inputSystem.isTriggered()` con el `PET_PROXIMITY_ENTER` y `PET_PROXIMITY_LEAVE` tipos de event para reaccionar cuando un jugador entra o sale del rango de proximidad de una entity. Esto es útil para mostrar feedback extra en entities activadas por proximidad, por ejemplo reproduciendo un sonido o una animación.

Para que esto funcione, la entity debe tener un `PointerEvents` component con el tipo de proximity event correspondiente definido.

```ts
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_PROXIMITY_ENTER,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 5,
			},
		},
		{
			eventType: PointerEventType.PET_PROXIMITY_LEAVE,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxDistance: 5,
				showFeedback: false,
			},
		},
	],
})

engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_PROXIMITY_ENTER, myEntity)) {
		console.log('Player entered proximity')
	}
	if (inputSystem.isTriggered(InputAction.IA_POINTER, PointerEventType.PET_PROXIMITY_LEAVE, myEntity)) {
		console.log('Player left proximity')
	}
})
```

## 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, usa `inputSystem.getInputCommand`Esta función devuelve la estructura de datos completa con información sobre el input event.

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

Si no hubo ninguna input action que coincida con la consulta, entonces `inputSystem.getInputCommand` devuelve *null*. Asegúrate de manejar este escenario en tu lógica.

### Distancia máxima de click

Para imponer una distancia máxima, de modo que una entity solo sea clickable a corta distancia, obtén `hit.length` propiedad de los datos del event.

```ts
// implement a system to handle the pointer event
engine.addSystem(() => {
	// fetch data about the pointer event
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// check if the click was close enough
	if (cmd && cmd.hit && cmd.hit.length < 6) {
		// hacer algo
	}
})
```

{% hint style="warning" %}
**📔 Nota**: Si ignoras cualquier event que esté lejos, asegúrate de configurar el `maxDistance` parámetro en el `PointerEvents` component para comportarse de forma consistente.
{% endhint %}

### Diferentes meshes dentro de un modelo

A menudo, *.glTF* Los modelos 3D están compuestos por múltiples meshes, y cada una tiene un nombre interno individual. Todos los button events incluyen la información de qué mesh específica se hizo click, así que puedes usar esta información para activar diferentes comportamientos de click en cada caso.

Para ver cómo se nombran las meshes dentro del modelo, debes abrir el modelo 3D con una herramienta de edición, como [Blender](https://www.blender.org/) por ejemplo.

![](https://1216664193-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-c0c8238fe31b8eb541ccb25d29459670a994f03e%2Fmesh-names%20\(1\).png?alt=media)

{% hint style="info" %}
**💡 Consejo**: También puedes averiguar el nombre de la mesh sobre la que se hizo click registrándola y leyéndola en la console.
{% endhint %}

Accedes a la `meshName` propiedad como parte del `impacto` objeto que devuelve el click event.

En el ejemplo de abajo tenemos un modelo de casa que incluye una mesh llamada `firePlace`. Queremos encender la chimenea solo cuando se haga click en su mesh correspondiente.

```ts
engine.addSystem(() => {
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)
	if (cmd && cmd.hit?.meshName === 'firePlace') {
		// light fire
	}
})
```

{% hint style="warning" %}
**📔 Nota**: Esto solo aplica a events basados en pointer, no a events basados en proximidad, ya que en ese caso todas las meshes del model podrían estar cerca del jugador al mismo tiempo.
{% endhint %}


---

# 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/system-based-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.
