Component

Provides access to a component instance of a specified component type.

Example: This is how you extend this class to create your own custom component:

 1import { Component, Type } from '@wonderlandengine/api';
 2
 3export class MyComponent extends Component {
 4    static TypeName = 'my-component';
 5    static Properties = {
 6        myBoolean: { type: Type.Boolean, default: false },
 7    };
 8    start() {}
 9    onActivate() {}
10    onDeactivate() {}
11    update(dt) {}
12}

In a component, the scene can be accessed using this.scene:

1import { Component, Type } from '@wonderlandengine/api';
2
3export class MyComponent extends Component {
4    static TypeName = 'my-component';
5    start() {
6        const obj = this.scene.addObject();
7    }
8}

.InheritProperties: boolean 

When set to true, the child class inherits from the parent properties, as shown in the following example:

 1import {Component, Property} from '@wonderlandengine/api';
 2
 3class Parent extends Component {
 4    static TypeName = 'parent';
 5    static Properties = {parentName: Property.string('parent')}
 6}
 7
 8class Child extends Parent {
 9    static TypeName = 'child';
10    static Properties = {name: Property.string('child')}
11    static InheritProperties = true;
12
13    start() {
14        // Works because `InheritProperties` is `true`.
15        console.log(`${this.name} inherits from ${this.parentName}`);
16    }
17}

Note: Properties defined in descendant classes will override properties with the same name defined in ancestor classes.

Defaults to true.

.Properties: Record<string, ComponentProperty

Properties of this component class.

Properties are public attributes that can be configured via the Wonderland Editor.

Example:

1import { Component, Type } from '@wonderlandengine/api';
2class MyComponent extends Component {
3    static TypeName = 'my-component';
4    static Properties = {
5        myBoolean: { type: Type.Boolean, default: false },
6        myFloat: { type: Type.Float, default: false },
7        myTexture: { type: Type.Texture, default: null },
8    };
9}

Properties are automatically added to each component instance, and are accessible like any JS attribute:

 1// Creates a new component and set each properties value:
 2const myComponent = object.addComponent(MyComponent, {
 3    myBoolean: true,
 4    myFloat: 42.0,
 5    myTexture: null
 6});
 7
 8// You can also override the properties on the instance:
 9myComponent.myBoolean = false;
10myComponent.myFloat = -42.0;

References 

Reference types (i.e., mesh, object, etc…) can also be listed as required:

 1import {Component, Property} from '@wonderlandengine/api';
 2
 3class MyComponent extends Component {
 4    static Properties = {
 5        myObject: Property.object({required: true}),
 6        myAnimation: Property.animation({required: true}),
 7        myTexture: Property.texture({required: true}),
 8        myMesh: Property.mesh({required: true}),
 9    }
10}

Please note that references are validated once before the call to start only, via the validateProperties method.

.TypeName: string 

Unique identifier for this component class.

This is used to register, add, and retrieve components of a given type.

.onRegister: (engine: WonderlandEngine) ⇒ void 

Called when this component class is registered.

Example: This callback can be used to register dependencies of a component, e.g., component classes that need to be registered in order to add them at runtime with addComponent, independent of whether they are used in the editor.

1class Spawner extends Component {
2    static TypeName = 'spawner';
3
4    static onRegister(engine) {
5        engine.registerComponent(SpawnedComponent);
6    }
7
8    // You can now use addComponent with SpawnedComponent
9}

Example: This callback can be used to register different implementations of a component depending on client features or API versions.

 1// Properties need to be the same for all implementations!
 2const SharedProperties = {};
 3
 4class Anchor extends Component {
 5    static TypeName = 'spawner';
 6    static Properties = SharedProperties;
 7
 8    static onRegister(engine) {
 9        if(navigator.xr === undefined) {
10            /* WebXR unsupported, keep this dummy component */
11            return;
12        }
13        /* WebXR supported! Override already registered dummy implementation
14         * with one depending on hit-test API support */
15        engine.registerComponent(window.HitTestSource === undefined ?
16            AnchorWithoutHitTest : AnchorWithHitTest);
17    }
18
19    // This one implements no functions
20}

.active: boolean 

true if the component is marked as active and its scene is active.

.active 

Set whether this component is active.

Activating/deactivating a component comes at a small cost of reordering components in the respective component manager. This function therefore is not a trivial assignment.

Does nothing if the component is already activated/deactivated.

.engine: WonderlandEngine 

Hosting engine instance.

.isDestroyed: boolean 

1.1.1+

true if the component is destroyed, false otherwise.

If erasePrototypeOnDestroy is true, reading a custom property will not work:

1engine.erasePrototypeOnDestroy = true;
2
3const comp = obj.addComponent('mesh');
4comp.customParam = 'Hello World!';
5
6console.log(comp.isDestroyed); // Prints `false`
7comp.destroy();
8console.log(comp.isDestroyed); // Prints `true`
9console.log(comp.customParam); // Throws an error

.markedActive: boolean 

true if the component is marked as active in the scene, false otherwise.

Note: At the opposite of active, this accessor doesn’t take into account whether the scene is active or not.

.object: Object3D 

The object this component is attached to.

.scene: Prefab 

Scene this component is part of.

.type: string 

The name of this component’s type

.copy(src: Record<string, any>) ⇒ Component 

Copy all the properties from src into this instance.

Note: Only properties are copied. If a component needs to copy extra data, it needs to override this method.

Example 

1class MyComponent extends Component {
2    nonPropertyData = 'Hello World';
3
4    copy(src) {
5        super.copy(src);
6        this.nonPropertyData = src.nonPropertyData;
7        return this;
8    }
9}

Note: This method is called by clone. Do not attempt to: - Create new component - Read references to other objects

When cloning via clone, this method will be called before start.

Note: JavaScript component properties aren’t retargeted. Thus, references inside the source object will not be retargeted to the destination object, at the exception of the skin data on MeshComponent and AnimationComponent.

Returns: Reference to self (for method chaining).

ParamTypeDescription
srcRecord<string, any>The source component to copy from.

.destroy() ⇒ void 

0.9.0+

Remove this component from its objects and destroy it.

It is best practice to set the component to null after, to ensure it does not get used later.

1   c.destroy();
2   c = null;

.equals(otherComponent: undefined | null | Component) ⇒ boolean 

Checks equality by comparing ids and not the JavaScript reference.

Deprecate: Use JavaScript reference comparison instead:

1const componentA = obj.addComponent('mesh');
2const componentB = obj.addComponent('mesh');
3const componentC = componentB;
4console.log(componentA === componentB); // false
5console.log(componentA === componentA); // true
6console.log(componentB === componentC); // true
ParamTypeDescription
otherComponentundefined | null | Component

.init() ⇒ void 

Triggered when the component is initialized by the runtime. This method will only be triggered once after instantiation.

Note: During the initialization phase, this.scene will not match engine.scene, since engine.scene references the active scene:

 1import {Component} from '@wonderlandengine/api';
 2
 3class MyComponent extends Component{
 4    init() {
 5        const activeScene = this.engine.scene;
 6        console.log(this.scene === activeScene); // Prints `false`
 7    }
 8    start() {
 9        const activeScene = this.engine.scene;
10        console.log(this.scene === activeScene); // Prints `true`
11    }
12}

.onActivate() ⇒ void 

Triggered when the component goes from an inactive state to an active state.

Note: When using (switchTo), all the components that were previously active will trigger this method.

Note: You can manually activate or deactivate a component using: active.

.onDeactivate() ⇒ void 

Triggered when the component goes from an activated state to an inactive state.

Note: When using (switchTo), the components of the scene getting deactivated will trigger this method.

Note: You can manually activate or deactivate a component using: active.

.onDestroy() ⇒ void 

0.9.0+

Triggered when the component is removed from its object. For more information, please have a look at onDestroy.

Note: This method will not be triggered for inactive scene being destroyed.

.reset() ⇒ Component 

Deprecated: Use resetProperties instead.

.resetProperties() ⇒ Component 

Reset the component properties to default.

Note: This is automatically called during the component instantiation.

Returns: Reference to self (for method chaining).

.start() ⇒ void 

Triggered when the component is started by the runtime, or activated.

You can use that to re-initialize the state of the component.

.toString() ⇒ string 

.update(delta: number) ⇒ void 

Triggered every frame by the runtime.

You should perform your business logic in this method. Example:

 1import { Component, Type } from '@wonderlandengine/api';
 2
 3class TranslateForwardComponent extends Component {
 4    static TypeName = 'translate-forward-component';
 5    static Properties = {
 6        speed: { type: Type.Float, default: 1.0 }
 7    };
 8    constructor() {
 9        this._forward = new Float32Array([0, 0, 0]);
10    }
11    update(dt) {
12        this.object.getForward(this._forward);
13        this._forward[0] *= this.speed;
14        this._forward[1] *= this.speed;
15        this._forward[2] *= this.speed;
16        this.object.translate(this._forward);
17    }
18}
ParamTypeDescription
deltanumberElapsed time between this frame and the previous one, in seconds.

.validateProperties() ⇒ void 

Validate the properties on this instance.

Throws: If any of the required properties isn’t initialized on this instance.