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

# Eventos basados en Systems

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

También puedes usar un system para detectar [global input events](#global-input-events), de modo que la escena reaccione siempre que se presione una tecla, sin tener en cuenta hacia dónde apunta el cursor del jugador.

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

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

Para que una entidad sea interactiva, debe tener un [collider](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-de-contenido-3d/colliders.md). Ver [obstáculos](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/click-events.md#obstacles) para más detalles. Esto también se aplica a los eventos de clic por proximidad.

## Usando un system

Comprueba los eventos de botón ejecutando una de las funciones auxiliares en el `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 clic en el puntero. En cada tick, comprueba si se pulsó el botón. Si `inputSystem.isTriggered()` devuelve *true*, el system ejecuta alguna lógica personalizada en 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 pueden llamarse de forma similar en cada tick:

* `inputSystem.isTriggered`: Devuelve true si ocurrió una acción de entrada desde el último tick.
* `inputSystem.isPressed`: Devuelve true si una entrada se está manteniendo pulsada actualmente. Devolverá true en cada tick hasta que el botón se suelte de nuevo.
* `inputSystem.getInputCommand`: Devuelve un objeto con datos sobre la acción de entrada.

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

Al manejar eventos de botón en una entidad, ofrece siempre retroalimentación al jugador, para que el jugador sea consciente de que se puede interactuar con una entidad. Si agregas un `PointerEvents` component a una entidad, los jugadores verán una pista mientras colocan el cursor sobre esa entidad. Consulta [Mostrar feedback](#show-feedback) para aprender cómo puedes agregar hints al pasar el cursor sobre entidades interactivas.

### Eventos de entrada globales

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

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

El ejemplo anterior comprueba si se pulsó el botón, independientemente de dónde esté el puntero o de qué entidades puedan estar en su trayectoria.

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

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

Cada entidad con la que quieras interactuar debe tener tanto un [`PointerEvents` componente](#show-feedback) y un [collider](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-de-contenido-3d/colliders.md).
{% endhint %}

El `inputSystem.isTriggered` function toma los siguientes argumentos obligatorios:

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

### Activar una entidad

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

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

// crear system
engine.addSystem(() => {
	if (
		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 se pulsó con el botón del puntero (botón izquierdo del mouse) una sola entidad codificada de forma fija.

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

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

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

{% hint style="warning" %}
**📔 Nota**: y un [collider](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-de-contenido-3d/colliders.md). Ver [obstáculos](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/click-events.md#obstacles) para más detalles.
{% endhint %}

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

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

{% hint style="warning" %}
**📔 Nota**: Cada entidad con la que quieras interactuar debe tener tanto un [`PointerEvents` componente](#show-feedback) y un [collider](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-de-contenido-3d/colliders.md).
{% endhint %}

Consulta [Datos de la acción de input](#data-from-input-action) para más información. Este método también te proporciona datos más detallados sobre el impacto del evento del puntero.

### Liberación del botón de entrada

También puedes comprobar eventos de liberación del puntero de manera muy similar, usando `PointerEventType.PET_UP`.

```ts
engine.addSystem(() => {
	if (
		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 liberación del puntero contra una entidad específica, no se tiene en cuenta hacia dónde apuntaba el cursor cuando se pulsó el botón. Solo considera hacia dónde apunta el cursor cuando se suelta el botón.

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

### Comprobar botones pulsados

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

```ts
engine.addSystem(() => {
	if (inputSystem.isPressed(InputAction.IA_POINTER)) {
		// Lógica en respuesta a que el botón se mantenga pulsado
	}
})
```

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

El `inputSystem.isPressed` function toma un único argumento:

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

### Manejar múltiples entidades

Si tu escena tiene múltiples entidades que se ven afectadas por los eventos del puntero 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) {
		if (
			inputSystem.isTriggered(
				InputAction.IA_POINTER,
				PointerEventType.PET_DOWN,
				entity
			)
		) {
			// Lógica en respuesta a interactuar con una entidad
		}
	}
})
```

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

En lugar de iterar sobre *todos* las entidades con un `PointerEvents` component en un único system, quizá quieras escribir distintos systems para manejar entidades que deban comportarse de forma diferente. El enfoque recomendado es marcar distintos tipos de entidades con [custom components](/creator/content-creator-es/scenes-sdk7/arquitectura/custom-components.md), e iterar sobre ellas en systems separados.

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

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

Este ejemplo tiene un system que itera sobre todas las entidades que tienen un custom component llamado `IsDoor` y otro que itera sobre todas las entidades que tienen un custom component llamado `isGem`. En ambos systems, comprueba cada entidad coincidente para ver si fue activada con el botón del puntero.

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

\## Múltiples botones en una entidad

Usando helpers como `pointerEventsSystem.onPointerDown`, cada entidad está limitada a tener un solo tipo de evento. No puedes registrar dos eventos de botón diferentes. No tienes esa limitación al usar eventos basados en system. Por ejemplo, aquí hay una entidad con la que los jugadores pueden interactuar tanto pulsando E como F, y cada acción desencadena 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 feedback

Para mostrar hints de UI mientras apuntas a una entidad, usa las propiedades en el `PointerEvents` componente.

```ts
// create entity
const myEntity = engine.addEntity()

// dar a la entidad un component PointerEvents
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 entidad, la UI mostrará un hover hint para indicar que se puede interactuar con la entidad. Consulta las secciones de abajo para ver los detalles de lo que puedes configurar.

{% hint style="warning" %}
**📔 Nota**: La `PointerEvents` component solo se encarga de mostrar la retroalimentación de hover. Para manejar los propios eventos de botón con lógica personalizada, consulta [Using-a-system](#check-for-events).
{% endhint %}

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

* `eventType`: Qué tipo de evento escuchar, como un valor del `PointerEventType` enum. Ver [Tipos de pointer events](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/click-events.md#types-of-pointer-events) para las opciones compatibles.
* `eventInfo`: Un objeto que puede contener los siguientes campos:
  * `botón` (*requerido*): Qué entrada escuchar, como un valor del `InputAction` enum. Ver [Botones de Pointer](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/click-events.md#pointer-buttons) para las opciones compatibles.
  * `hoverText` *(opcional)*: Qué string mostrar en la pista de feedback al pasar el cursor. "Interact" por defecto.
  * `hideFeedback` *(opcional)*: Si es true, oculta tanto la pista de hover como el resaltado del borde para esta Entity. *false* por defecto.
  * `showHighlight` *(opcional)*: Si es true, los players verán el resaltado del borde cuando pasen el cursor sobre la Entity. *true* por defecto. Este valor solo se considera si `hideFeedback` es *false*.
  * `maxDistance` *(opcional)*: Muestra feedback solo cuando el jugador está a menos de cierta distancia de la entidad. El valor predeterminado es *10 metros*.

Un solo `PointerEvents` component puede contener múltiples definiciones de eventos del puntero, que pueden detectar distintos eventos para distintos botones. Cada entidad solo puede tener *uno* `PointerEvents` component, pero este component puede incluir múltiples objetos en su `pointerEvents` array, uno por cada evento 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 evento del puntero, mostradas radialmente alrededor del cursor.

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

```ts
// create entity
const myEntity = engine.addEntity()

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

// manejar eventos de clic en la entidad
engine.addSystem(() => {
	if (inputSystem.isTriggered(InputAction.IA_POINTER, myEntity)) {
		// Lógica personalizada en respuesta a una acción de entrada
	}
})
```

### Feedback al hacer hover

Cuando un jugador coloca el cursor sobre un objeto con un `PointerEvents` component, ve:

* Un resaltado del borde en la Entity
* Una pista de hover cerca del cursor con un icono para el botón que necesitan pulsar y un string que dice "Interact".

Estos elementos se pueden activar/desactivar y personalizar.

El feedback de hover en la UI muestra un icono diferente según el input 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 mouse para `InputAction.IA_POINTER`.

Cambia el string cambiando el `hoverText` valor. Mantén este string corto, para que se lea rápido y no resulte demasiado intrusivo en la pantalla.

```ts
// create entity
const chest = engine.addEntity()

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

En el ejemplo anterior, el evento del puntero incluye un valor para `hoverText`. Este campo define la cadena que se mostrará en la UI mientras el jugador apunta a la entidad. De forma predeterminada, esta cadena dice *Interact*.

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

Si una entidad tiene múltiples eventos del puntero, los hints de hover para cada uno de ellos se muestran radialmente alrededor del cursor.

El `hoverText` de un `.UP` evento del puntero solo se muestra mientras el jugador ya mantiene pulsada la tecla correspondiente y apunta a la entidad.

Si una entity tiene tanto un `DOWN` evento del puntero y un `UP` evento del puntero, el hint para la `DOWN` acción se muestra mientras el botón no se está pulsando. El hint cambia al del `UP` evento solo cuando el botón se pulsa y permanece pulsado.

```ts
// create entity
const entity = engine.addEntity()

// dar a la entidad un component PointerEvents
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 pista de hover, pero dejar el resaltado del borde, establece el valor de `hoverText` en "".

```ts
// create entity
const chest = engine.addEntity()

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

Para ocultar el resaltado del borde pero dejar la pista de hover, establece `showHighlight` en *false*.

```ts
// create entity
const chest = engine.addEntity()

// dar a la entidad un component PointerEvents
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hoverText: 'Open door',
				showHighlight: false,
			},
		},
	],
})
```

Para ocultar tanto la pista de hover como el resaltado del borde, establece el `hideFeedback` a true. Al hacer esto, el cursor no muestra iconos, texto ni ningún resaltado de borde. También podrías simplemente eliminar el `PointerEvents` component de la entidad.

```ts
// create entity
const chest = engine.addEntity()

// dar a la entidad un component PointerEvents
PointerEvents.create(chest, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_DOWN,
			eventInfo: {
				button: InputAction.IA_POINTER,
				hideFeedback: true,
			},
		},
	],
})
```

### Distancia máxima

Algunas entidades pueden estar diseñadas para ser interactivas solo a corta distancia. Si un jugador está demasiado lejos de una entidad, el hover hint no se mostrará junto al cursor.

De forma predeterminada, solo se puede hacer clic en las entidades cuando el jugador está dentro de una distancia corta de la entidad, con una distancia máxima de *10 metros*. Puedes cambiar la distancia máxima configurando la propiedad `maxDistance` de un evento del puntero.

```ts
// create entity
const myEntity = engine.addEntity()

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

// implementar un system para manejar el evento del puntero
engine.addSystem(() => {
	// obtener datos sobre el evento del puntero
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// comprobar si el clic estuvo lo suficientemente cerca
	if (cmd.hit.length < 6) {
		// haz algo
	}
})
```

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

{% hint style="warning" %}
**📔 Nota**: La `maxDistance` se mide en metros desde la cámara del jugador. Ten en cuenta que en tercera persona la cámara está un poco más lejos, así que asegúrate de que la distancia que configures funcione bien en ambos modos.
{% endhint %}

## Hints personalizados avanzados

El `PointerEvents` component añade fácilmente hints de UI cuando el cursor del jugador empieza a pasar sobre una entidad. Generalmente es bueno que los hints se comporten de forma coherente con lo que los jugadores están acostumbrados a ver en otras escenas de Decentraland. Sin embargo, en algunos casos quizá quieras señalar 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 entidad. También podrías mostrar un resaltado brillante alrededor de la entidad mientras se pasa el cursor, y ocultarlo cuando ya no se esté pasando. También podría usarse para mecánicas de juego específicas.

Usa la `inputSystem.isTriggered()` function 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 entidad, y cada vez que el cursor deja de apuntar a él.

El ejemplo siguiente agranda las entidades hasta un tamaño de *1.5* cuando el cursor empieza a apuntar a su collider, y las vuelve a poner en un tamaño de *1* cuando el cursor las deja.

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

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

{% hint style="warning" %}
**📔 Nota**: Cada entidad con la que quieras interactuar debe tener tanto un [`PointerEvents` componente](#show-feedback) y un [collider](/creator/content-creator-es/scenes-sdk7/conceptos-basicos-de-contenido-3d/colliders.md).
{% endhint %}

## Eventos de proximidad

Comprueba las pulsaciones de botones de proximidad sin importar hacia dónde apunta el cursor usando `PET_DOWN` en una entidad que use `InteractionType.PROXIMITY`. Configura el campo `interactionType` en el `eventInfo` para marcar el evento como basado en proximidad.

Consulta [**Eventos de Proximity**](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/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',
				maxPlayerDistance: 5
			},
			interactionType: InteractionType.PROXIMITY,
		},
	],
})

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

Usando helpers como `pointerEventsSystem.onProximityDown`, cada entidad está limitada a tener un solo tipo de evento. No puedes registrar dos eventos de botón diferentes, ni siquiera una combinación de eventos de proximidad y de puntero usando el mismo botón. No tienes esa limitación al usar eventos basados en system. Por ejemplo, aquí hay una entidad con la que se puede interactuar tanto apuntando con el cursor y pulsando E, como acercándose a ella y pulsando E sin apuntarla con el cursor.

```ts
	PointerEvents.create(myEntity, {
        pointerEvents: [
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_POINTER,
                    hoverText: 'Click',
                    maxPlayerDistance: 15,
                },
                interactionType: InteractionType.CURSOR,
            },
            {
                eventType: PointerEventType.PET_DOWN,
                eventInfo: {
                    button: InputAction.IA_PRIMARY,
                    hoverText: 'Press E',
                    maxPlayerDistance: 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 los `PET_PROXIMITY_ENTER` y `PET_PROXIMITY_LEAVE` tipos de evento para reaccionar cuando un jugador entra o sale del rango de proximidad de una entidad. Esto es útil para mostrar feedback adicional en entidades activadas por proximidad, por ejemplo reproduciendo un sonido o una animación.

Para que esto funcione, la entidad debe tener un `PointerEvents` component con el tipo de evento de proximidad correspondiente definido.

```ts
PointerEvents.create(myEntity, {
	pointerEvents: [
		{
			eventType: PointerEventType.PET_PROXIMITY_ENTER,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxPlayerDistance: 5,
			},
		},
		{
			eventType: PointerEventType.PET_PROXIMITY_LEAVE,
			eventInfo: {
				button: InputAction.IA_POINTER,
				maxPlayerDistance: 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 input

Obtén datos de una acción de input, como el botón que se pulsó, la Entity que fue impactada, la dirección y longitud del ray, etc. Consulta ([Ver documentación](https://github.com/decentraland/docs/blob/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 completa de datos con información sobre el evento de entrada.

```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 acción de entrada que coincida con la consulta, entonces `inputSystem.getInputCommand` devuelve undefined. Asegúrate de manejar este escenario en tu lógica.

### Distancia máxima de clic

Para imponer una distancia máxima, de modo que una entidad solo pueda pulsarse a corta distancia, obtén `hit.length` propiedad de los datos del evento.

```ts
// implementar un system para manejar el evento del puntero
engine.addSystem(() => {
	// obtener datos sobre el evento del puntero
	const cmd = inputSystem.getInputCommand(
		InputAction.IA_POINTER,
		PointerEventType.PET_DOWN,
		myEntity
	)

	// comprobar si el clic estuvo lo suficientemente cerca
	if (cmd && cmd.hit.length < 6) {
		// haz algo
	}
})
```

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

### Diferentes meshes dentro de un modelo

A menudo, *.glTF* los modelos 3D están formados por múltiples meshes, y cada uno tiene un nombre interno individual. Todos los eventos de botón incluyen la información de qué mesh específica fue pulsada, así que puedes usar esta información para desencadenar distintos comportamientos de clic 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.

![](/files/55d3fe277452096ee81933052c8c263af5af60ed)

{% hint style="info" %}
**💡 Consejo**: También puedes averiguar el nombre del mesh pulsado registrándolo y leyéndolo en la consola.
{% endhint %}

Accedes a la propiedad `meshName` como parte del `hit` objeto, que se devuelve por el evento de clic.

En el ejemplo de abajo tenemos un modelo de casa que incluye un mesh llamado `firePlace`. Queremos encender la chimenea solo cuando se pulse su mesh correspondiente.

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

{% hint style="warning" %}
**📔 Nota**: Esto solo se aplica a eventos basados en el puntero, no a eventos basados en proximidad, ya que en ese caso todos los meshes del modelo podrían estar a la vez en proximidad del jugador.
{% 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-boton/system-based-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
