For the complete documentation index, see llms.txt. This page is also available as Markdown.

Eventos basados en Systems

Aprende cómo gestionar los clics de usuario en tu escena.

Si tu scene tiene múltiples entities similares que se activan con la misma lógica, puedes escribir un único system para iterar sobre todas ellas y describir ese comportamiento solo una vez. Esta también es la opción más eficiente y más orientado a los datos enfoque.

También puedes usar un system para detectar eventos globales de entrada, para que la escena reaccione cada vez que se pulsa una tecla, sin importar hacia dónde apunta el cursor del player.

Si lo único que quieres hacer es hacer clic o pulsar un botón en una sola entity para activarla, la forma más fácil es usar el Registrar un callback enfoque.

Para establecer una lógica personalizada más específica, quizá quieras trabajar con los datos en bruto y usar el Avanzado enfoque.

Para que una entity sea interactiva, debe tener un collider. Consulta obstáculos para más detalles. Esto también se aplica a los eventos de clic por proximidad.

Usar 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.

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

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

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

  • inputSystem.isTriggered: Devuelve true si una input action ocurrió desde el último tick.

  • inputSystem.isPressed: Devuelve true si una input se está pulsando actualmente. Devolverá true en cada tick hasta que el botón se suelte de nuevo.

  • inputSystem.getInputCommand: Devuelve un object con datos sobre la input action.

Consulta las secciones a continuación para más detalles sobre cada una.

Al manejar eventos de botón en una entity, proporciona siempre feedback al player, para que sepa que se puede interactuar con una entity. Si añades un PointerEvents component a una entity, los players verán una hint al pasar el cursor sobre esa entity. Consulta Mostrar feedback para aprender cómo puedes añadir hover hints en entities interactivas.

Eventos de input globales

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

El ejemplo anterior comprueba si se pulsó el botón, sin importar dónde esté el pointer ni qué entities 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.

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

  • InputAction: Qué input escuchar, como un value de InputAction : Ver Botones del puntero para las opciones compatibles.

  • PointerEventType: Qué tipo de event escuchar, como un value de PointerEventType : Ver Tipos de pointer events para las opciones compatibles.

Activar una entity

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

El ejemplo anterior comprueba en cada tick si una sola entity codificada de forma fija se pulsó con el botón del pointer (botón izquierdo del mouse).

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

  • InputAction: Qué input escuchar, como un value de InputAction : Ver Botones del puntero para las opciones compatibles.

  • PointerEventType: Qué tipo de event escuchar, como un value de PointerEventType : Ver Tipos de pointer events para las opciones compatibles.

  • Entity (opcional): Qué entity usar para comprobar estos events. Si no se proporciona ningún value, comprobará pulsaciones globales del botón, sin importar hacia dónde apuntaba el cursor del player.

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 podrá detectarse mediante ninguna de las funciones de inputSystem. Consulta Mostrar feedback para más detalles sobre el PointerEvents componente.

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

Consulta Datos de la acción de entrada para más info. Este method también te proporciona datos más detallados sobre el hit del pointer event.

Liberación del botón de input

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

Comprobar botones pulsados

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

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

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

  • InputAction: Qué input escuchar, como un value de InputAction : Ver Botones del puntero para las opciones compatibles.

Manejar múltiples entities

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

Este ejemplo usa un consulta de components 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, lleva a cabo lógica personalizada.

En lugar de iterar sobre todo las entities con un PointerEvents component en un único system, quizá quieras escribir systems diferentes para manejar entities que deban comportarse de maneras distintas. El enfoque recomendado es marcar diferentes tipos de entities con custom components, e iterarlas en systems separados.

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

Esta forma de organizar el código de tu scene es muy orientado a los datos y debería dar como resultado 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 eventos de botón diferentes. No tienes esa limitación cuando usas events basados en system. Por ejemplo, aquí hay una entity con la que los players pueden interactuar tanto pulsando E como F, y cada uno activa funcionalidades diferentes.

Mostrar feedback

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

Cada vez que el cursor del player apunte a los colliders de esta entity, la UI mostrará una hover hint para indicar que se puede interactuar con la entity. Consulta las secciones a continuación para ver los detalles de lo que puedes configurar.

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

  • eventType: Qué tipo de event escuchar, como un value de PointerEventType : Ver Tipos de pointer events para las opciones compatibles.

  • eventInfo: Un object que puede contener los siguientes fields:

    • button (requerido): Qué input escuchar, como un value de InputAction : Ver Botones del puntero para las opciones compatibles.

    • hoverText (opcional): Qué cadena mostrar en la sugerencia de feedback al pasar el cursor. "Interact" por defecto.

    • showFeedback (opcional): Si es false, oculta tanto la sugerencia al pasar el cursor como el resaltado de borde para esta entidad. true por defecto.

    • showHighlight (opcional): Si es true, los jugadores verán el resaltado de borde cuando pasen el cursor sobre la entidad. true por defecto. Este valor solo se considera si showFeedback es true.

    • maxDistance (opcional): Muestra feedback solo cuando el player esté a una distancia menor que una cierta distancia de la entity. El default es 10 metros.

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

Los players verán varias etiquetas, una por cada pointer event, mostradas radialmente alrededor del cursor.

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

Retroalimentación al pasar el cursor

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

  • Un resaltado de borde en la entidad

  • Una sugerencia al pasar el cursor cerca del puntero con un icono del botón que deben presionar y una cadena que dice "Interact".

Estos elementos se pueden activar/desactivar y personalizar.

El feedback 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.

En el ejemplo anterior, el pointer event incluye un value para hoverText. Este field define la string que se muestra en la UI mientras el player apunta a la entity. De forma predeterminada, esta string dice Interactuar.

💡 Consejo: La hoverText La string debe describir la acción que ocurre al interactuar. Por ejemplo Abrir, Activar, Coger, Seleccionar. Estas strings deben ser lo más cortas posible, para evitar distraer demasiado al player.

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

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

Si una entidad tiene tanto un DOWN pointer event y un UP La action se muestra mientras el botón no está siendo pulsado. La hint cambia a la del DOWN event solo cuando el botón se pulsa y permanece pulsado. UP event only when the button is pressed and remains pressed.

Para ocultar la sugerencia al pasar el cursor, pero dejar el resaltado de borde, establece el valor de la hoverText hoverText

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

Para ocultar tanto la sugerencia al pasar el cursor como el resaltado de borde, establece showFeedback en false. Al hacerlo, el cursor no muestra ningún icono, texto ni resaltado de bordes. También podrías simplemente eliminar el PointerEvents component de la entity.

Distancia máxima

Algunas entities pueden estar diseñadas intencionalmente para ser interactivas solo a corta distancia. Si un player está demasiado lejos de una entity, la hover hint no se mostrará junto al cursor.

De forma predeterminada, las entities solo se pueden clicar cuando el player está a corta distancia de la entity, con una distancia máxima de 10 metros. Puedes cambiar la distancia máxima configurando la maxDistance property de un pointer event.

El ejemplo anterior establece la distancia máxima para las 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 para saber cómo obtener la distancia de una input action.

Pistas personalizadas avanzadas

El PointerEvents component añade fácilmente pistas de UI cuando el cursor del player empieza a pasar sobre una entity. En general, es bueno que las pistas se comporten de forma consistente con lo que los players están acostumbrados a ver en otras scenes 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 player empieza a pasar el cursor sobre la entity. También podrías mostrar un resaltado brillante alrededor de la entity mientras se mantiene el cursor encima, y ocultarlo cuando ya no esté encima. También podría usarse para mecánicas de gameplay específicas.

Usa la 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 player empieza a apuntar al collider de la entity, y cada vez que el cursor deja de apuntar a él.

El ejemplo siguiente agranda las entities a un tamaño de 1.5 cuando el cursor empieza a apuntar a su collider, y las vuelve a colocar en un tamaño de 1 cuando el cursor deja de apuntar a ellas.

Eventos de proximidad

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

Consulta Eventos de proximidad para más detalles, incluidas las funciones auxiliares disponibles.

Usando helpers como pointerEventsSystem.onProximityDown, cada entity está limitada a tener un solo tipo de event. No puedes registrar dos eventos de botón diferentes, ni siquiera una combinación de eventos de proximidad y pointer usando el mismo botón. No tienes esa limitación cuando usas events basados en system. Por ejemplo, aquí hay una entity 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.

También puedes usar inputSystem.isTriggered() con los PET_PROXIMITY_ENTER y PET_PROXIMITY_LEAVE event types para reaccionar cuando un player entra o sale del rango de proximidad de una entity. Esto es útil para mostrar feedback adicional en entities activadas por proximidad, por ejemplo reproducir 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.

Datos de la acción de entrada

Obtén datos de una acción de entrada, como el botón que se pulsó, la entidad que fue alcanzada, la dirección y la longitud del rayo, etc. Consulta (Ver documentación) para obtener 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 datos sobre el input event.

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 clic

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

Diferentes meshes dentro de un model

A menudo, .glTF los 3D models están formados por múltiples meshes, cada uno con un nombre interno individual. Todos los button events incluyen información sobre qué mesh específico se pulsó, así que puedes usar esta información para activar diferentes comportamientos de clic en cada caso.

Para ver cómo se llaman los meshes dentro del model, debes abrir el 3D model con una herramienta de edición, como Blender por ejemplo.



💡 Consejo: También puedes averiguar el nombre del mesh pulsado registrándolo y leyéndolo en la consola.

Accedes a la meshName property como parte del hit object que devuelve el click event.

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

Última actualización