> 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/escenas-sdk7/interactividad/eventos-de-boton/proximity-events.md).

# Eventos de proximidad

Las interacciones de proximidad permiten que las Entities reaccionen a eventos de botón cuando un player entra, está cerca y mira aproximadamente hacia ella, sin requerir que apunte su cursor a la Entity.

Los eventos tradicionales de puntero usan ray-casting: el player debe apuntar su cursor al collider de una Entity antes de poder presionar un botón para activar el evento. En cambio, los eventos de proximidad comprueban Entities que están dentro de un área determinada alrededor del avatar, sin importar hacia dónde esté apuntando el cursor del player.

El área interactiva considerada para las interacciones de proximidad es una amplia sección triangular de una esfera, que se proyecta hacia adelante desde la posición del player. A diferencia de los eventos de puntero, la dirección hacia la que mira el avatar es importante, independientemente de la dirección hacia la que mira la cámara.

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

Para que una Entity sea interactiva, debe tener un [collider](/creator/content-creator-es/escenas-sdk7/conceptos-basicos-de-contenido-3d/colliders.md). Consulta [obstáculos](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/click-events.md#obstacles) para más detalles.

## Registrar callbacks de proximidad

El `pointerEventsSystem` incluye funciones auxiliares para eventos de proximidad, siguiendo el mismo patrón que [los callbacks de eventos de puntero](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/register-callback.md).

### Pulsaciones de botón por proximidad

Usa `pointerEventsSystem.onProximityDown` para detectar pulsaciones de botón mientras el player está dentro del rango. A diferencia de `onPointerDown`, esto no requiere que el player apunte su cursor a la Entity.

```ts
pointerEventsSystem.onProximityDown(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Pulsa E',
            maxPlayerDistance: 5,
        },
    },
    function () {
        console.log('El player presionó el botón cerca de la Entity')
    }
)
```

Usa `pointerEventsSystem.onProximityUp` para detectar cuándo el player suelta un botón mientras está dentro del rango.

```ts
pointerEventsSystem.onProximityUp(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Suelta E',
            maxPlayerDistance: 5,
        },
    },
    function () {
        console.log('El player soltó el botón cerca de la Entity')
    }
)
```

{% hint style="warning" %}
**📔 Nota**: Solo uno `onProximityDown` y uno `onProximityUp` puede registrarse por Entity. Una vez agregados, siguen escuchando hasta que se eliminen. No los llames dentro de un loop de System, ya que eso seguiría reescribiendo el comportamiento.
{% endhint %}

## Tipos de eventos de proximidad

Se han agregado dos nuevos valores al `PointerEventType` enum:

* `PET_PROXIMITY_ENTER`: Se activa cuando el player entra en el rango de proximidad de la Entity.
* `PET_PROXIMITY_LEAVE`: Se activa cuando el player sale del rango de proximidad de la Entity.

Estos se pueden usar con un `PointerEvents` component y el `inputSystem` para el [enfoque basado en System](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/system-based-events.md#proximity-events). Ese enfoque también admite pulsaciones de botón por proximidad usando el `InteractionType.PROXIMITY` campo.

## Prioridad

Cuando varias Entities están dentro del rango y podrían responder a la misma entrada, solo una se activa, por defecto la más cercana. Usa el `priority` campo para controlar cuál tiene prioridad. Las Entities con un **número más alto** como valor de prioridad responden primero.

Si el player está tanto dentro del rango de una Entity con una interacción de proximidad como si el cursor del player apunta a una Entity que tiene una interacción de puntero, la Entity con la interacción de puntero siempre tiene prioridad. De nuevo, solo una Entity se activa.

```ts
pointerEventsSystem.onProximityDown(
    {
        entity: doorEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Abrir puerta',
            maxPlayerDistance: 5,
            priority: 2,
        },
    },
    function () {
        console.log('Puerta activada')
    }
)

pointerEventsSystem.onProximityDown(
    {
        entity: floorEntity,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Pisa aquí',
            maxPlayerDistance: 5,
            priority: 1,
        },
    },
    function () {
        console.log('Suelo activado')
    }
)
```

En el ejemplo anterior, si ambas Entities están dentro del rango, la Entity de la puerta responde porque tiene la prioridad más alta.

El `priority` El campo también se puede establecer en las propiedades de un `PointerEvents` componente.

## Opciones

Las funciones de ayuda de proximidad aceptan las mismas opciones que sus equivalentes de puntero:

* `button`: Qué botón escuchar. Consulta [Botones de puntero](/creator/content-creator-es/escenas-sdk7/interactividad/eventos-de-boton/click-events.md#pointer-buttons) para las opciones compatibles.
* `maxDistance`: Distancia máxima desde la **camera** hasta la Entity, en metros.
* `maxPlayerDistance`: Distancia máxima desde la **avatar** hasta la Entity, en metros. Esta es la configuración más relevante para los eventos de proximidad.
* `hoverText`: Texto para mostrar en la UI cuando el player está cerca de la Entity.
* `showHighlight`: Si es true, muestra un resaltado de borde en la Entity cuando el player está dentro del rango. *true* de forma predeterminada.
* `showFeedback`: Si es true, muestra retroalimentación de hover, flotando alrededor del centro de la Entity. *true* de forma predeterminada.
* `priority`: Resuelve conflictos cuando varias Entities están en proximidad. Los valores más altos tienen prioridad. Si varias Entities tienen el mismo valor de prioridad, se elige la más cercana.

## Eliminar callbacks

Para eliminar un callback de proximidad, usa la función de eliminación correspondiente:

```ts
pointerEventsSystem.removeOnProximityDown(myEntity)
pointerEventsSystem.removeOnProximityUp(myEntity)
pointerEventsSystem.removeOnProximityEnter(myEntity)
pointerEventsSystem.removeOnProximityLeave(myEntity)
```

Una vez eliminada, la Entity ya no reacciona a ese evento de proximidad.

## Entrada y salida de proximidad

Usa `pointerEventsSystem.onProximityEnter` para ejecutar un callback cuando el player entra en el rango de proximidad de la Entity, y `pointerEventsSystem.onProximityLeave` cuando sale. Esto se puede usar para mostrar pistas de feedback adicionales al player, por ejemplo un sonido o una animación cuando se puede interactuar con un objeto.

```ts
pointerEventsSystem.onProximityEnter(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_POINTER,
            hoverText: 'Cerca',
            maxPlayerDistance: 5,
        },
    },
    function () {
        console.log('El player entró en proximidad')
    }
)

pointerEventsSystem.onProximityLeave(
    {
        entity: myEntity,
        opts: {
            button: InputAction.IA_POINTER,
            hoverText: 'Cerca',
            maxPlayerDistance: 5,
        },
    },
    function () {
        console.log('El player salió de proximidad')
    }
)
```

## Ejemplo: puerta de proximidad

El siguiente ejemplo abre o cierra una puerta cuando el player presiona un botón mientras está cerca, sin necesidad de apuntar a la puerta.

```ts
const doorPivot = engine.addEntity()
Transform.create(doorPivot, { position: Vector3.create(3, 0, 4) })

const door = engine.addEntity()
GltfContainer.create(door, { src: 'assets/door.glb' })
Transform.create(door, { position: Vector3.create(-1, 0, 0), parent: doorPivot })

let isDoorOpen = false
const closedRot = Quaternion.fromEulerDegrees(0, 0, 0)
const openRot = Quaternion.fromEulerDegrees(0, 90, 0)

pointerEventsSystem.onProximityDown(
    {
        entity: door,
        opts: {
            button: InputAction.IA_PRIMARY,
            hoverText: 'Abrir / Cerrar',
            maxPlayerDistance: 5,
            priority: 1,
        },
    },
    function () {
        if (isDoorOpen) {
            Tween.setRotate(doorPivot, openRot, closedRot, 700)
            isDoorOpen = false
        } else {
            Tween.setRotate(doorPivot, closedRot, openRot, 700)
            isDoorOpen = true
        }
    }
)
```


---

# 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/escenas-sdk7/interactividad/eventos-de-boton/proximity-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.
