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

Entities & Components

Aprende lo esencial sobre entities y components en una escena de Decentraland

Las escenas de Decentraland se construyen en torno a entities, components y systems. Este es un patrón común usado en la arquitectura de varios motores de juego, que permite una fácil componibilidad y escalabilidad.



Descripción general

Entities son la unidad básica para construirlo todo en las escenas de Decentraland. Todos los objetos 3D visibles e invisibles y los reproductores de audio de tu scene serán, cada uno, una entity. Una entity no es más que un id, al que pueden hacer referencia los components. La entity en sí no tiene propiedades ni métodos propios; simplemente sirve para agrupar varios components.

Components definen las características de una entity. Por ejemplo, un Transform component almacena las coordenadas, rotación y escala de la entity. Un MeshRenderer component le da a la entity una forma visible (como un cubo o una esfera) cuando se renderiza en la scene; un Material component le da a la entity un color o una textura. También puedes crear custom components para servir con los datos que requiere tu scene, por ejemplo un custom health podría almacenar el valor de salud restante de una entity, y añadirlo a entities que representen enemigos no jugadores en un juego.

Si estás familiarizado con el desarrollo web, piensa en las entities como el equivalente de Elements en un DOM tree, y en los components como attributes de esos elements.

En el Scene Editor in Creator Hub, puedes ver los components que pertenecen a una entity seleccionándola.




Components como Transform, Material o cualquiera de los shape components están estrechamente ligados a la renderización de la scene. Si los valores de estos components cambian, eso basta para que el engine cambie cómo se renderiza la scene en el siguiente frame.

El engine es la parte de la scene que se sitúa en el centro y gestiona todas las demás partes. Determina qué entities se renderizan y cómo interactúan los players con ellas. También coordina qué functions de systems se ejecutan y cuándo.

Los components están pensados para almacenar datos sobre su entity referenciada. Solo pueden almacenar estos datos, no pueden modificar estos datos por sí mismos. Todos los cambios en los valores de los components los llevan a cabo los Systems. Los Systems están completamente desacoplados de los components y de las entities en sí. Entities y components son agnósticos a qué systems actúan sobre ellos.

Sintaxis para entities y components

El ejemplo siguiente muestra algunas operaciones básicas para declarar y configurar entities y components básicas.

Cuando se crea un component, siempre se asigna a una entity padre. Los valores del component luego afectan a la entity.

💡 Consejo: En lugar de crear entities una por una, puedes generar de una vez todo un tree de entities y components a partir de un archivo compuesto .

Eliminar entities

Para eliminar una entity del engine, usa engine.removeEntity(). Esta función devuelve un booleano: true si la entity se eliminó, false si se rechazó la eliminación.

Si una entity eliminada tiene any child entities, estas cambian su parent de vuelta al entity predeterminado, engine.RootEntity que se posiciona en la base de la scene, con una escala de 1.

Entities reservadas por el renderer

Algunos ids de entity están reservados por el renderer para los avatares de jugadores remotos. No puedes eliminar estas entities. Si llamas a engine.removeEntity() en una entity reservada por el renderer, devuelve false y deja todos los components intactos.

El entities reservadas con nombre (engine.RootEntity, engine.PlayerEntity, engine.CameraEntity) son un caso especial: engine.removeEntity() sigue devolviendo false para estas (sus ids nunca se liberan), pero sus components son eliminados. Esto significa que puedes limpiar tus propios components de ellas (por ejemplo, eliminando un InputModifier de engine.PlayerEntity), aunque el id de la entity en sí nunca se libera.

Puedes comprobar el valor de retorno al eliminar entities para manejar casos límite:

Eliminar una entity con sus children

Para eliminar una entity y también todos sus children (y los children de sus children, de forma recursiva), usa el helper removeEntityWithChildren() .

💡 Consejo: En lugar de eliminar una entity del engine, en algunos casos puede ser mejor hacerla invisible, por si quieres poder cargarla otra vez sin retraso. Consulta Hacer invisible

Eliminar entities detrás de escena

Una entity es solo un id referenciado por sus components. Así que al eliminar una entity en realidad estás eliminando cada uno de los components que referencian esta entity. Si eliminas manualmente todos los components de una entity, para el player se verá igual que hacer engine.removeEntity(). Sin embargo, engine.removeEntity() también realiza un poco de contabilidad interna adicional, marcando el id de entity como ya no en uso, por lo que siempre es la forma recomendada de eliminar una entity.

Entities anidadas

Una entity puede tener otras entities como children. Gracias a esto, podemos organizar entities en trees, igual que el HTML de una página web.



Para establecer una entity como parent de otra, la entity hija debe tener un Transform component Transform. Entonces puedes establecer el parent field con una referencia a la entity padre.

Una vez asignado un parent, este puede leerse desde la entity hija mediante el parent field de su Transform component.

Si una entity padre tiene un Transform component que afecta a su posición, escala o rotación, sus entities hijas también se ven afectadas. Los valores de posición o rotación se suman, y los valores de escala se multiplican.

Si la entity padre o hija no tiene un Transform component, se usan los siguientes valores predeterminados.

  • Para position, el centro del padre es 0, 0, 0

  • Para rotation la rotación del padre es el quaternion 0, 0, 0, 1 (equivalente a los ángulos de Euler 0, 0, 0)

  • Para scale, se considera que el padre tiene un tamaño de 1. Cualquier redimensionamiento del padre afecta a la escala y a la posición en proporción.

Las entities que no tienen component de shape son invisibles en la scene. Pueden usarse como envoltorios para manejar y posicionar varias entities como un grupo.

Para separar una entity hija de su parent, puedes asignar el parent de la entity a engine.RootEntity.

En el Scene Editor, puedes ver toda la jerarquía de entities anidadas en tu scene en el panel de la izquierda.



Obtener una entity por ID

Cada entity en tu scene tiene un número único id. Puedes recuperar un component que hace referencia a una entity específica desde el engine basándote en este ID.

Por ejemplo, si el click de un player o un raycast impacta una entity, esto devolverá el id de la entity impactada, y puedes usar el comando anterior para obtener el component Transform de la entity que coincide con ese id. También puedes obtener cualquier otro component de esa entity de la misma manera.

Obtener una entity por nombre

Al añadir entities mediante arrastrar y soltar en el Scene Editor, cada entity tiene un nombre único. Usa la función engine.getEntityOrNullByName() para referenciar una de estas entities desde tu código. Pasa el nombre de la entity como una string, tal como aparece en la UI del Scene Editor, en la vista de tree de la izquierda.

Tienes libertad para realizar cualquier acción sobre una entity recuperada mediante este método, como añadir o eliminar components, modificar valores de components existentes o eliminar la entity del engine.

Todas las entities añadidas mediante la UI del Scene Editor tienen un component Name , puedes iterar sobre todas ellas así:

Añadir o reemplazar un component

Cada entity solo puede tener un component de un tipo dado. Por ejemplo, si intentas asignar un Transform a una entity que ya tiene uno, esto provocará un error.

Para evitar este error, puedes usar .createOrReplace en lugar de .create. Este comando sobrescribe cualquier component existente del mismo tipo si existe, y si no, crea un nuevo component igual que .create.

Acceder a un component desde una entity

Puedes acceder a los components de una entity usando la .get() o las funciones getMutable() .

El get() function obtiene una referencia de solo lectura al component. No puedes cambiar ningún valor de este component desde esta referencia.

Si quieres cambiar los valores del component, usa la función getMutable() en su lugar. Si cambias los valores en la versión mutable del component, estás afectando directamente a la entity a la que pertenece ese component.

Ver datos mutables para más detalles.

El ejemplo anterior modifica directamente el valor de la x escala en el component Transform.

Si no estás completamente seguro de que la entity tenga el component que intentas recuperar, usa getOrNull() o getMutableOrNull().

Si el component que intentas recuperar no existe en la entity:

  • get() y getMutable() devuelve un error.

  • getOrNull() y getMutableOrNull() devuelve Null.

Eliminar un component de una entity

Para eliminar un component de una entity, usa el método deleteFrom() del tipo de component.

Si intentas eliminar un component que no existe en la entity, esta acción no generará ningún error.

Comprobar si hay un component

Puedes comprobar si una entity tiene una instancia de cierto component usando la función has() . Esta función devuelve true si el component está presente, y false si no lo está. Esto puede ser muy útil para usarlo en lógica condicional en tu scene.

💡 Consejo: También puedes consultar components para obtener una lista completa de components que contienen un component específico, o un conjunto específico de components. No iteres manualmente sobre todas las entities de la scene para comprobar cada una con un has(), ese enfoque es mucho menos eficiente.

Comprobar cambios en un component

Usa la onChange function para ejecutar una función callback cada vez que los valores del component cambien para una determinada entity. Esto funciona con cualquier component, y es un gran atajo para ayudar a que tu código siga siendo legible.

La función callback puede incluir un parámetro de entrada que contenga el nuevo estado del component.

Si el component se elimina de la entity, entonces la función se llama con una entrada de undefined.

💡 Consejo: La función .onChange() funciona tanto con los components nativos del SDK como con custom components definidos por el creador.

Obtener entities hijas

Para acceder a todas las entities que son hijas directas de una entity padre, usa getEntitiesWithParent. Toma como argumentos el engine y la parent entity y devuelve una lista de todas las entities que tienen esa entity concreta como parent. Ten en cuenta que solo devuelve children directos, no children de children.

Para acceder en su lugar a todos los descendientes de una Entity, sin importar qué tan profundamente anidados estén, usa la función getComponentEntityTree(). En lugar de recorrer manualmente la jerarquía nivel por nivel, esta función devuelve una lista plana de todos los descendientes que es fácil de iterar. También filtra para incluir solo las entities que tienen un Component dado o una lista de Components.

El getComponentEntityTree function toma tres parámetros:

  • engine: La instancia de engine que ejecuta las entities

  • entity: La Entity raíz desde la que comenzar

  • component: El Component por el que filtrar (normalmente Transform para jerarquías espaciales)

La función devuelve un generador que emite cada Entity descendiente en la estructura de árbol. Solo se incluirán en los resultados las entities que tengan el Component especificado.

Puedes combinar esto con otras comprobaciones de Component para encontrar entities específicas en tu jerarquía:

Entidades reservadas

Ciertos ids de Entity están reservados para entidades especiales que existen en cada Scene. Se puede acceder a ellas mediante los siguientes alias:

  • engine.RootEntity

  • engine.PlayerEntity

  • engine.CameraEntity

La Entity raíz

Todas las entities de la Scene son children de la engine.RootEntity, directamente o indirectamente.

Esta Entity no tiene un Component Transform, pero se usa para gestionar varios Components que representan ajustes más globales, como control del skybox, posición del cursor, o dimensiones de la pantalla.

La Entity player

El engine.PlayerEntity entity representa el avatar del player.

Obtener el Transform Component del player para obtener la posición y rotación actuales del player, consulta datos de usuario. El Transform del player es de solo lectura; para modificarlo usa la movePlayerTo() function, aprende más.

También puedes adjuntar objetos al player estableciéndolos como children de esta entity, aunque la Attach to Player suele ser la mejor opción para eso.

La Entity camera

El engine.CameraEntity entity representa la camera del player.

Obtener el Transform Component de la camera para obtener la posición y rotación de la camera. El Transform de esta entity también es de solo lectura. Para modificar el ángulo o la posición de la camera, usa una cámara virtual.

También puedes obtener el CameraMode Component para saber si el player está usando el modo de camera en primera o tercera persona, consulta modo de camera.

Última actualización