Benutzerdefinierte Komponenten
Einführung
Benutzerdefinierte Komponenten können das visuelle Erscheinungsbild, die physikalischen Eigenschaften, die Eingabeverarbeitung oder die benutzerdefinierte Spiellogik definieren.Erstellen einer benutzerdefinierten Komponente
Um eine benutzerdefinierte Komponente zu erstellen, gehen Sie folgendermaßen vor:
- Klicken Sie im Dateibrowser auf die Plus-Schaltfläche (+).
- Klicken Sie auf "Neue Datei" → "Neue Komponentendatei" und geben Sie ihr einen Namen (Dateierweiterung optional).
- Es wird eine neue Komponentendatei, standardmäßig TypeScript, in Ihrem Projekt erzeugt.
- Die neue Komponentendatei enthält den für die Registrierung der benutzerdefinierten Komponente erforderlichen Boilerplate-Code.
Registrieren einer benutzerdefinierten Komponente
Der folgende Code ist ein Beispiel dafür, wie eine neu erstellte benutzerdefinierte Komponente im Code-Editor angezeigt wird:
Beispiel
Vermeiden Sie die Verwendung von "debug-" als Präfix für Komponentennamen. Komponentennamen, die mit 'debug-' beginnen, sind für interne Debugging-Zwecke reserviert und werden bei Verwendung in Ihrem Code nicht korrekt funktionieren.
// Dies ist eine Komponentendatei. Sie können diese Datei verwenden, um eine benutzerdefinierte Komponente für Ihr Projekt zu definieren.
// Diese Komponente wird als benutzerdefinierte Komponente im Editor angezeigt.
import * as ecs from '@8thwall/ecs' // So greifen Sie auf die ecs-Bibliothek zu.
ecs.registerComponent({
name: 'custom-component',
schema: {
// Fügen Sie Daten hinzu, die in der Komponente konfiguriert werden können.
},
schemaDefaults: {
// Fügen Sie Standardwerte für die Schemafelder hinzu.
},
data: {
// Hinzufügen von Daten, die nicht außerhalb der Komponente konfiguriert werden können.
},
add: (world, component) => {
// Wird ausgeführt, wenn die Komponente zur Welt hinzugefügt wird.
},
tick: (world, component) => {
// Läuft bei jedem Frame.
},
remove: (world, component) => {
// Läuft, wenn die Komponente aus der Welt entfernt wird.
},
})
Hinzufügen von benutzerdefinierten Komponenten zu einer Entität
Das folgende Beispiel zeigt, wie eine benutzerdefinierte Komponente zu einer vorhandenen Entität hinzugefügt werden kann.
Beispiel
Stellen Sie sicher, dass Sie die Komponente exportieren, bevor Sie versuchen, sie zu importieren oder irgendwo zu verwenden.
import * as ecs from '@8thwall/ecs'
const CustomComponent = ecs.registerComponent({
name: 'custom-component',
schema: {
foo: ecs.string
},
schemaDefaults: {
},
data: {
},
add: (world, component) => {
},
tick: (world, component) => {
},
remove: (world, component) => {
},
})
export {CustomComponent}
import CustomComponent from './custom-component' // Der Name der Datei ohne den Dateityp.
const demo = world.createEntity()
CustomComponent.set(world, demo, {
foo: 'bar'
})
Funktionen
Mit Komponentenfunktionen können Sie verschiedene Aktionen für eine Komponente und ihre Daten in Bezug auf eine Entität durchführen.
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.radius += 1;
cursor.height *= 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)
Schema
Ein Schema ist eine Liste von Schlüssel-Werte-Paaren, die die Struktur einer Komponente definiert. Der Schlüssel ist der Name der Eigenschaft, und der Wert ist ein ECS-Typ, der die Art der Daten angibt, die diese Eigenschaft enthalten wird.
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 |
Beispiel
Das folgende Beispiel zeigt das Schema einer benutzerdefinierten Komponente.
schema: {
target: ecs.eid, // Eindeutige Entitätsreferenz für den NSC (Entity ID)
speed: ecs.f32, // Bewegungsgeschwindigkeit des NSC (32-bit float)
strength: ecs.f64, // Stärkestufe des NSC (64-bit float)
level: ecs.i32, // Charakterstufe des NPCs (32-bit integer)
armor: ecs.ui8, // Rüstungswert des NPCs (0-255, 8-bit unsigned integer)
experience: ecs.ui32, // Erfahrungspunkte des NPCs (32-bit unsigned integer)
guildName: ecs.string, // Name der Gilde zu der der NPC gehört. (String)
isHostile: ecs.boolean // Boolescher Wert, der angibt, ob der NPC dem Spieler feindlich gesinnt ist (Boolean)
}
schemaDefaults: {
speed: 3.14,
strength: 5.8,
level: 10,
armor: 255,
experience: 12,
guildName: 'Niantic Crew'
isHostile: false
}