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

Custom Components

Crea un Component personalizado para manejar datos específicos relacionados con una Entity

Los datos sobre una entity se almacenan en su components. El Decentraland SDK proporciona una serie de base components que gestionan diferentes aspectos de una entity, como su posición, shape, material, etc. El engine sabe cómo interpretar la información en estos y cambiará cómo se renderiza la entity en consecuencia en cuanto cambien sus valores.

Si la lógica de tu scene requiere almacenar información sobre una entity que no es manejada por los components predeterminados del SDK, entonces puedes crear un tipo personalizado de component en tu scene. Luego puedes construir systems que comprueben los cambios en estos components y respondan en consecuencia.

Acerca de definir components

Para definir un nuevo component, usa engine.defineComponent. Cada component necesita lo siguiente:

  • Un componentName: Un identificador de string único que el SDK usa internamente para identificar este tipo de component. Puede ser cualquier string, siempre que sea único.

  • Un schema: Una class que define la estructura de datos que contiene el component.

  • default values (opcional): Un objeto que contiene los default values que se usarán para inicializar una copia del component, cuando estos no se proporcionen.

export const WheelSpinComponent = engine.defineComponent('wheelSpinComponent', {
	spinning: Schemas.Boolean,
	speed: Schemas.Float,
})

Una vez que hayas definido un custom component, puedes crear instances de este component, que referencian entities en la scene. Cuando creas una instance de un component, proporcionas values para cada uno de los fields en el schema del component. Los values deben cumplir con los tipos declarados de cada field.

// Crear entities
const wheel1 = engine.addEntity()
const wheel2 = engine.addEntity()

// Create instances of the component
WheelSpinComponent.create(wheel1, {
	spinning: true,
	speed: 10,
})

WheelSpinComponent.create(wheel2, {
	spinning: false,
	speed: 0,
})

Cada entity a la que se le agrega el component instancia una nueva copia del component, que contiene datos específicos para esa entity.

Tu custom component también puede realizar las otras funciones comunes que están disponibles en otros components:

Acerca de componentName

Cada component debe tener un nombre o identificador único de component, que lo diferencie internamente. No necesitarás usar este identificador interno en ninguna otra parte de tu código. Una buena práctica es usar el mismo nombre que asignas al component, pero empezando con una letra minúscula; sin embargo, lo que realmente importa es que este identificador sea único dentro del proyecto.

Al crear components que se compartirán como parte de una library, ten en cuenta que los nombres de los components en tu library no deben coincidir con ningún nombre de component en el proyecto donde se usa, ni con otras libraries que también utilice ese proyecto. Para evitar el riesgo de cualquier coincidencia, la mejor práctica recomendada es incluir el nombre de la library como parte de la componentName string. Puedes seguir esta fórmula: ${packageName}::${componentName}. Por ejemplo, si construyes unaMyUtilities library que incluye un MoveEntity component, establece el componentName de ese component en MyUtilities::moveEntity.

Components como flags

Es posible que quieras añadir un component que simplemente marque un entity para diferenciarlo de otros, sin usarlo para almacenar ningún dato. Para hacerlo, deja el schema como un objeto vacío.

Esto es especialmente útil al usar querying components. Un simple flag component puede usarse para distinguir entities de otras y evitar que el system itere sobre más entities de las necesarias.

Luego puedes crear un system que itere sobre todas las entities con este component.

Component Schemas

Un schema describe la estructura de los datos dentro de un component. Un component puede almacenar tantos fields como quieras, cada uno debe incluirse en la estructura del schema. El schema puede incluir tantos niveles de elementos anidados como necesites.

Cada field en el schema debe incluir una declaración de type. Solo puedes usar los special schema types proporcionados por el SDK. Por ejemplo, usa el type Schemas.Boolean en lugar de type boolean. Write Schemas. y tu IDE mostrará todas las opciones disponibles.

El ejemplo anterior define un component whose schema holds dos values, un spinning boolean y un speed floating point number.

Puedes elegir crear el schema inline mientras defines el component, o para mayor legibilidad puedes crearlo y luego referenciarlo.

💡 Consejo: Al crear una instance de un component, las opciones de autocompletado de VS Studio te sugerirán qué fields puedes agregar al component presionando Ctrl + Space.

Default Schema types

Los siguientes basic types están disponibles para usarse dentro de los fields de un schema:

  • Schemas.Boolean

  • Schemas.Byte

  • Schemas.Double

  • Schemas.Float

  • Schemas.Int

  • Schemas.Int64

  • Schemas.Number

  • Schemas.Short

  • Schemas.String

  • Schemas.Entity

También existen los siguientes complex types. Cada uno incluye una serie de nested properties con numerical values.

  • Schemas.Vector3

  • Schemas.Quaternion

  • Schemas.Color3

  • Schemas.Color4

💡 Consejo: Consulta Tipos de geometría y Color types para obtener más details sobre cómo son útiles estos types de data.

Por ejemplo, puedes usar estos schema types en un component como este para seguir el gradual movement de un entity. Este component almacena una initial y una final position como Vector3 values, así como una speed y una fraction del path completado como float numbers. Consulta Mover entidades para ver la implementación completa de este example.

Array types

Para set el type de un field como un array, usa Schemas.Array(). Pasa el type de los elements en el array como una property.

Nested schema types

Para set el type de un field to be an object, usa Schemas.Map(). Pasa el contents de este object como una property. Este nested object es esencialmente un schema en sí mismo, nested dentro del parent schema.

Alternativamente, para que todo sea más legible y reusable, podrías lograr lo mismo definiendo el nested schema por separado y luego referenciándolo al definir el parent schema.

Enums types

Puedes set que el type de un field en un schema sea un enum. Los enums facilitan elegir entre un número finito de opciones, proporcionando values legibles para cada una.

Para set que el type de un field sea un enum, primero debes definir el enum. Luego puedes referenciarlo usando Schemas.EnumNumber o Schemas.EnumString, según el type de enum. Estas functions toman dos parameters: el enum al que se hace referencia y un default value que se usará para este field.

Interchangeable types

Puedes set que el type de un field en un schema siga un oneOf pattern, where different types can be accepted.

Al crear una instance del component, necesitas especificar el selected type con un $case, for example:

Default values

A menudo es bueno tener default values en tus components, para que no sea necesario set explícitamente cada value cada vez que creas una nueva copy.

El engine.defineComponent() function toma un third argument, que te permite pasar un object con values que se usarán by default. Este object puede incluir todos o algunos de los values en el schema. Los fields que no estén cubiertos por los defaults ni por los values que proporciones al inicializar una copy del component se inicializan con un zero-like value, like 0, false, o una cadena vacía, depending on the type.

El example anterior crea un WheelSpinComponent component que incluye tanto un schema como un set de default values para usar. Si luego inicializas una copy de este component sin especificar ningún value, utilizará los establecidos en el default.

Suscribirse a los cambios

Un caso de uso común es ejecutar una function solo en caso de que los datos de cierto component cambien. Usa la OnChange function para evitar tener que definir un System y tener que comparar explícitamente los valores antiguos con los nuevos.

Construcción de systems para usar un component

Con tu component definido y agregado a entities en tu scene, puedes crear Systems para realizar lógica, haciendo uso de estos data almacenados en el component.

El ejemplo anterior define un system que itera sobre todas las entities que incluyen el custom wheelSpinComponent, y las rota ligeramente en cada tick del game loop. La cantidad de esta rotación es proporcional al speed valor almacenado en la instance del component de cada entity. El example hace uso de component queries para obtener solo las entities relevantes.

Última actualización