Componentes personalizados
Introducción
Los componentes personalizados pueden definir la apariencia visual, las propiedades físicas, el manejo de las entradas o la lógica de juego personalizada.Creación de un componente personalizado
Para crear un Componente personalizado, siga estos pasos:
- En el explorador de archivos, haga clic en el botón más (+).
- Haga clic en "Nuevo archivo" → "Nuevo archivo de componentes" y asígnele un nombre (extensión de archivo opcional).
- Se generará un nuevo archivo Component, TypeScript por defecto, en su proyecto.
- El nuevo archivo de componente incluirá el código requerido para registrar el componente personalizado.
Registro de un componente personalizado
El siguiente código es un ejemplo de cómo aparecerá un Componente Personalizado recién creado en el Editor de Código:
Ejemplo
Evite utilizar 'debug-' como prefijo para los nombres de los componentes. Los nombres de componentes que empiezan por 'debug-' están reservados para fines de depuración interna y no funcionarán correctamente si se utilizan en su código.
// Este es un archivo de componente. Puede utilizar este archivo para definir un componente personalizado para su proyecto.
// Este componente aparecerá como un componente personalizado en el editor.
import * as ecs from '@8thwall/ecs' // Así es como se accede a la biblioteca ecs.
ecs.registerComponent({
name: 'Custom Component',
// schema: {
// },
// schemaDefaults: {
// },
// data: {
// },
// add: (world, component) => {
// },
// tick: (world, component) => {
// },
// remove: (world, component) => {
// },
// stateMachine: ({world, eid, schemaAttribute, dataAttribute}) => {
// ecs.defineState('default').initial()
// },
})
Añadir componentes personalizados a una entidad
El siguiente ejemplo muestra cómo añadir un Componente personalizado a una entidad existente.
Ejemplo
Asegúrese de exportar el Componente antes de intentar importarlo o utilizarlo en cualquier sitio.
import * as ecs from '@8thwall/ecs'
const CustomComponent = ecs.registerComponent({
name: 'Componente personalizado',
schema: {
displayName: ecs.string
},
schemaDefaults: {
displayName: 'Unnamed'
},
})
export {CustomComponent}
import * as ecs from '@8thwall/ecs'
import {CustomComponent} from './custom-component'
ecs.registerComponent({
name: 'Otro componente personalizado',
stateMachine: ({world, eid, schemaAttribute, dataAttribute}) => {
ecs.defineState('default')
.initial()
.onEnter(() => {
const entity = world.createEntity()
CustomComponent.set(world, entity, {
displayName: 'Jini'
})
})
},
})
Funciones
Las funciones de componente permiten realizar diferentes acciones sobre un componente y sus datos en relación con una entidad.
Get
Returns a read-only reference.
Example
ecs.CylinderGeometry.get(world, component.eid)
Set
Ensures the component exists on the entity, then assigns the (optional) data to the component.
Example
ecs.CylinderGeometry.set(world, component.eid, {
radius: 1,
height: 1
})
Mutate
Perform an update to the component within a callback function. Return true
to indicate no changes made.
Example
ecs.CylinderGeometry.mutate(world, component.eid, (cursor) => {
cursor.radio += 1;
cursor.altura *= 2;
return false;
})
Remove
Removes the component from the entity.
Example
ecs.CylinderGeometry.remove(world, component.eid)
Has
Returns true
if the component is present on the entity.
Example
ecs.CylinderGeometry.has(world, component.eid)
Reset
Adds, or resets the component to its default state.
Example
ecs.CylinderGeometry.reset(world, component.eid)
Advanced Functions
Cursor
Returns a mutable reference. Cursors are reused so only one cursor for each component can exist at a time.
Example
ecs.CylinderGeometry.cursor(world, component.eid)
Acquire
Same behavior as cursor, but commit must be called after the cursor is done being used.
Example
ecs.CylinderGeometry.acquire(world, component.eid)
Commit
Called after acquire. An optional third argument determines whether the cursor was mutated or not.
Example
ecs.CylinderGeometry.commit(world, component.eid)
ecs.CylinderGeometry.commit(world, component.eid, false)
Dirty
Mark the entity as having been mutated. Only needed in a specific case where systems are mutating data.
Example
ecs.CylinderGeometry.dirty(world, component.eid)
Esquema
Un esquema es una lista de pares clave-valor que define la estructura de un Componente. La clave es el nombre de la propiedad, y el valor es un tipo ECS que especifica el tipo de datos que contendrá esa propiedad.
Currently, storing dynamically sized objects or lists isn’t supported. We’re actively exploring this feature and would love to hear about your specific use cases.
The following data types are useful for creating Schema properties on a Custom Component or references to a specific type.
Type | Description |
---|---|
ecs.eid | Entity Reference |
ecs.f32 | 32-bit floating-point number |
ecs.f64 | 64-bit floating-point number |
ecs.i32 | 32-bit integer |
ecs.ui8 | 8-bit unsigned integer |
ecs.ui32 | 32-bit unsigned integer |
ecs.string | String |
ecs.boolean | Boolean |
Ejemplo
El siguiente ejemplo muestra el esquema de un componente personalizado.
esquema: {
target: ecs.eid, // Referencia de entidad única para el PNJ (ID de entidad)
speed: ecs.f32, // Velocidad de movimiento del PNJ (flotante de 32 bits)
strength: ecs.f64, // Nivel de fuerza del PNJ (flotante de 64 bits)
level: ecs.i32, // Nivel de personaje del PNJ (entero de 32 bits)
armor: ecs.ui8, // Valor de armadura del PNJ (0-255, entero de 8 bits sin signo)
experience: ecs.ui32, // Puntos de experiencia del PNJ (entero de 32 bits sin signo)
guildName: ecs.string, // Nombre del gremio al que pertenece el PNJ. (String)
isHostile: ecs.boolean // Booleano que indica si el PNJ es hostil al jugador (Booleano)
}
schemaDefaults: {
velocidad: 3.14,
fuerza: 5.8,
nivel: 10,
armadura: 255,
experiencia: 12,
guildName: 'Niantic Crew'
isHostile: false
}
Campos personalizados del editor
La visualización y la funcionalidad de sus componentes en el editor de entidades pueden personalizarse de varias maneras. Todo esto se hace utilizando comentarios dentro del esquema donde los campos se marcan con // @
.
Etiquetas
A veces las etiquetas en el editor deben ser más descriptivas que sus nombres en el código.
esquema: {
// @label Foo
bar: ecs.eid,
},
Referencias de activos
Si necesita hacer referencia a un activo en el proyecto.
esquema: {
// @asset
yetiModel: ecs.string,
}
Mín y Máx
Si necesita bloquear valores para que no superen una determinada cantidad cuando se modifican en la interfaz. No afecta a los cambios de la variable en tiempo de ejecución.
esquema: {
// @min 0
// @max 128
goldCoins: ecs.i32,
}
Condiciones
Las propiedades pueden configurarse para que sólo se muestren en función de los valores de otras propiedades.
esquema: {
// 'from' sólo se mostrará si autoFrom está en false:
autoFrom: ecs.boolean,
// @condition autoFrom=false
from: ecs.f32,
// 'easingFunction' se mostrará si easeIn o easeOut están establecidos:
easeIn: ecs.boolean,
easeOut: ecs.boolean,
// @condition easeIn=true|easeOut=true
easingFunction: ecs.string,
// 'targetX' sólo se muestra si no hay objetivo establecido:
target: ecs.eid,
// @condition target=null
targetX: ecs.f32,
}
Enumeraciones
Las propiedades de cadena pueden limitarse a una lista de conjuntos:
esquema: {
// @enum Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential
easingFunction: ecs.string,
}
Grupos
Ciertos grupos de propiedades pueden ser instruidos para ser tratados especialmente en el editor. Los grupos se configuran de la siguiente manera:
- El inicio y el final del grupo se marcan con // @group start … y // @grupo fin
- Las condiciones se pueden aplicar a todo el grupo con // @group condition
- Actualmente se admiten dos tipos de grupo: vector3 y color
Etiquetas
Se pueden seguir utilizando etiquetas personalizadas para campos individuales:
esquema: {
// @group start orient:vector3
// @label Pitch
orientPitch: ecs.f32,
// @label Yaw
orientYaw: ecs.f32,
// @label Roll
orientRoll: ecs.f32,
// @group end
}
Vector3
Los grupos de propiedades que representan vectores 3D pueden indicarse del siguiente modo:
esquema: {
autoFrom: ecs.boolean,
// @group start from:vector3
// @group condition autoFrom=false
fromX: ecs.f32,
fromY: ecs.f32,
fromZ: ecs.f32,
// @group end
}
Color
Los colores pueden indicarse como en el siguiente ejemplo:
esquema: {
// @group start background:color
bgRed: ecs.f32,
bgGreen: ecs.f32,
bgBlue: ecs.f32,
// @group end
}
Datos
Datos es similar a Esquema, sin embargo hay dos diferencias notables.
- Los datos no pueden leerse o escribirse fuera del Componente en el que están definidos.
- Los datos no tienen valores por defecto, sin embargo pueden establecerse en el método de ciclo de vida 'add' para una funcionalidad similar.
Cursores
Un Cursor es una referencia al esquema de otro Componente adjunto a una entidad. Puedes pensar en él como un puntero o manejador que te permite leer o escribir propiedades.
Sin embargo, tenlo en cuenta:
- Los cursores pueden volverse obsoletos si se utilizan de forma asíncrona (por ejemplo, dentro de setTimeout, o callbacks retardados). Utilice schemaAttribute y dataAttribute en su lugar en estos casos.
- Los cursores proporcionan acceso directo a los datos de una entidad, lo que significa que modificar un cursor cambia directamente el valor en el mundo.
Métodos del ciclo de vida
Método | Descripción |
---|---|
añada | Se ejecuta una vez cuando se inicializa el componente. Se utiliza para establecer el estado inicial e instanciar variables |
eliminar | Llamado cuando el Componente es removido de la entidad o cuando la entidad es separada de la escena. Sirve para deshacer todas las modificaciones anteriores de la entidad. |
garrapata | Llamada en cada bucle de renderizado o tick de la escena. Se utiliza para cambios o comprobaciones continuas. |
Parámetros
Propiedad | Tipo | Descripción |
---|---|---|
mundo | Mundo | Referencia al mundo. |
componente | ComponentObject | Referencia al Componente actual. |
ComponentObject
Utilice schemaAttribute o dataAttribute en lugar de las propiedades eid, schema o data en contextos asíncronos como temporizadores o controladores de eventos.
Propiedad | Tipo | Descripción |
---|---|---|
eid | eid | ID de entidad del componente actual |
esquema | Cursor | Referencia al esquema de la entidad actual |
esquemaAtributo | ComponentObject | Referencia al esquema del componente actual en el ámbito mundial. |
datos | Cursor | Referencia a los datos de la Entidad actual |
dataAttribute | ComponentObject | Referencia a los datos del componente actual en World Scope. |