Skip to content

Script

We have introduced the Component in the Component Lifecycle, users can extend from ComponentBase class to develop custom components. Users can customize the running logic by overwriting the lifecycle functions of the component base class:

  • Initialize/stop: like init and destroy
  • State change: like start, onEnable and onDisable
  • Update logic: like onUpdate, onLateUpdate and onBeforeUpdate

Basic Usage

Add a custom script to an entity

ts
class Script extends ComponentBase {
    //Overwrite init
    public init() {
        //This function is called when the component is created, and can be used to initialize internal variables
        //Note that the component has not been mounted to the Object3D at this time, so it cannot be accessed by this.object3D
    }
    // Overwrite start
    public start() {
        // This function is called before the component starts rendering,
        // At this time, you can access this.object3D to get the attributes of the node or other components
    }
    // Overwrite onUpdate
    public onUpdate() {
        // This function is called every frame rendering loop, usually defined the node's loop logic
        // For example, update the rotation angle of the object every frame
        this.object3D.rotationY += 1;
    }
}

let ball: Object3D = new Object3D();
ball.addComponent(Script);

In a custom script, you can get the object3D object which current component mounted through this.object3D, and then change the object state.
A key point of game or animation development is to update the behavior, state and orientation of the object before each frame rendering. These update operations can usually be defined in the onUpdate callback of the component itself. The engine will automatically register the onUpdate callback to the main loop to achieve the update logic of each frame.

Examples

Here are three different script animation examples to show you more complex script component usage.

1. Light Animation Script Component


WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { ComponentBase, Time, DirectLight, Color, LitMaterial, MeshRenderer, Scene3D, BoxGeometry, Object3D, Engine3D, Camera3D, HoverCameraController, View3D, AtmosphericComponent } from '@orillusion/core';

class LightAnimation extends ComponentBase {
    private light: DirectLight;
    private color: Color;

    public start() {
        this.light = this.object3D.getComponent(DirectLight);
        this.color = this.light.lightColor;
    }
    public onUpdate() {
        this.color.r = Math.pow(Math.sin(Time.time * 0.001), 10);
        this.light.lightColor = this.color;
    }
}

class UserLogic {
    private scene: Scene3D;
    private cube: Object3D;
    private light: DirectLight;

    init(scene3D: Scene3D) {
        this.scene = scene3D;
        this.createCube();
        this.createLight();
        this.createComponents();
    }

    private createCube() {
        let mat = new LitMaterial();
        mat.roughness = 1.0;
        let obj: Object3D = new Object3D();
        let geometry = new BoxGeometry(3, 3, 3);
        let mr = obj.addComponent(MeshRenderer);
        mr.material = mat;
        mr.geometry = geometry;
        this.scene.addChild(obj);
    }

    private createLight() {
        let light: Object3D = new Object3D();
        let component = light.addComponent(DirectLight);
        light.rotationX = -45;
        light.rotationZ = -45;
        component.lightColor = new Color(1.0, 0, 0, 1);
        component.intensity = 10;
        this.scene.addChild(light);
        this.light = component;
    }

    private createComponents() {
        this.light.object3D.addComponent(LightAnimation);
    }

    async run() {
        await Engine3D.init();
        this.init(new Scene3D());
        let cameraObj = new Object3D();
        let camera = cameraObj.addComponent(Camera3D);
        camera.perspective(60, Engine3D.aspect, 1, 5000.0);
        let controller = camera.object3D.addComponent(HoverCameraController);
        controller.setCamera(-135, 0, 15);
        this.scene.addChild(cameraObj);
        // add an Atmospheric sky enviroment
        this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
        // create a view with target scene and camera
        let view = new View3D();
        view.scene = this.scene;
        view.camera = camera;
        // start render
        Engine3D.startRenderView(view);
    }
}
new UserLogic().run();
ts
class LightAnimation extends ComponentBase {
    private light: DirectLight;
    private color: Color;

    // Overwrite start initialize variables of start
    protected start() {
        this.light = this.object3D.getComponent(DirectLight);
        this.color = this.light.lightColor;
    }

    onUpdate() {
        // Update lightColor
        this.color.r = Math.pow(Math.sin(Time.time * 0.001), 10);
        this.light.lightColor = this.color;
    }
}

Here we change the red component of the light color every frame, so that it changes with time, and finally produces the effect of light animation.

2. Material Animation Script Component


WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { ComponentBase, Time, DirectLight, Color, LitMaterial, MeshRenderer, Scene3D, BoxGeometry, Object3D, Engine3D, Camera3D, HoverCameraController, BloomPost, View3D, AtmosphericComponent, PostProcessingComponent } from '@orillusion/core';

class MaterialAnimation extends ComponentBase {
    private material: LitMaterial;
    private time: number = 0;

    start() {
        let mr = this.object3D.getComponent(MeshRenderer);
        this.material = mr.material as LitMaterial;
    }

    public onUpdate() {
        let delta = Time.time * 0.001;
        this.material.baseColor = new Color(Math.sin(delta), Math.cos(delta), Math.sin(delta));
    }
}

class UserLogic {
    private scene: Scene3D;
    private cube: Object3D;
    private light: DirectLight;

    init(scene3D: Scene3D) {
        this.scene = scene3D;
        this.createCube();
        this.createLight();
        this.createComponents();
    }

    private createCube() {
        let mat = new LitMaterial();
        let obj: Object3D = new Object3D();
        let geometry = new BoxGeometry(3, 3, 3);
        let mr = obj.addComponent(MeshRenderer);
        mr.material = mat;
        mr.geometry = geometry;
        this.cube = obj;
        this.scene.addChild(obj);
    }

    private createLight() {
        let light: Object3D = new Object3D();
        let component = light.addComponent(DirectLight);
        light.rotationX = 45;
        light.rotationY = 30;
        component.lightColor = new Color(1, 1, 1, 1);
        component.intensity = 2;
        this.scene.addChild(light);
        this.light = component;
    }

    private createComponents() {
        this.cube.addComponent(MaterialAnimation);
    }

    async run() {
        await Engine3D.init();
        this.init(new Scene3D());
        let cameraObj = new Object3D();
        let camera = cameraObj.addComponent(Camera3D);
        camera.perspective(60, Engine3D.aspect, 1, 5000.0);
        let controller = camera.object3D.addComponent(HoverCameraController);
        controller.setCamera(45, 0, 15);
        this.scene.addChild(cameraObj);

        // add an Atmospheric sky enviroment
        this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
        // create a view with target scene and camera
        let view = new View3D();
        view.scene = this.scene;
        view.camera = camera;
        // start render
        Engine3D.startRenderView(view);

        // add a bloom post
        let postProcessing = this.scene.addComponent(PostProcessingComponent);
        postProcessing.addPost(BloomPost);
    }
}
new UserLogic().run();
ts
class MaterialAnimation extends ComponentBase {
    private material: LitMaterial;

    // Overwrite start initialize variables of start
    protected start() {
        let mr = this.object3D.getComponent(MeshRenderer);
        this.material = mr.material;
    }

    onUpdate() {
        // Update baseColor
        let delta = Time.time * 0.001
        this.material.baseColor = new Color(Math.sin(delta), Math.cos(delta), Math.sin(delta));
    }
}

Similar to above, we can change the material object of the object, such as changing the material color according to the time, so as to achieve the corresponding animation effect.

3. Path Animation Script Component


WebGPU is not supported in your browser
Please upgrade to latest Chrome/Edge

<
ts
import { ComponentBase, Time, DirectLight, Color, LitMaterial, MeshRenderer, Scene3D, BoxGeometry, Object3D, Engine3D, Camera3D, HoverCameraController, View3D, AtmosphericComponent } from '@orillusion/core';

class PathAnimation extends ComponentBase {
    onUpdate() {
        this.object3D.x = Math.sin(Time.time * 0.001) * 2;
        this.object3D.y = Math.cos(Time.time * 0.001) * 2;
    }
}

class UserLogic {
    private scene: Scene3D;
    private cube: Object3D;
    private light: DirectLight;

    init(scene3D: Scene3D) {
        this.scene = scene3D;
        this.createCube();
        this.createLight();
        this.createComponents();
    }

    private createCube() {
        let mat = new LitMaterial();
        let obj: Object3D = new Object3D();
        let geometry = new BoxGeometry(3, 3, 3);
        let mr = obj.addComponent(MeshRenderer);
        mr.material = mat;
        mr.geometry = geometry;
        this.scene.addChild(obj);
        this.cube = obj;
    }

    private createLight() {
        let light: Object3D = new Object3D();
        let component = light.addComponent(DirectLight);
        light.rotationX = 45;
        light.rotationY = 30;
        component.lightColor = new Color(1.0, 1.0, 0, 1);
        component.intensity = 2;
        this.scene.addChild(light);
        this.light = component;
    }

    private createComponents() {
        this.cube.addComponent(PathAnimation);
    }

    async run() {
        await Engine3D.init();
        this.init(new Scene3D());
        let cameraObj = new Object3D();
        let camera = cameraObj.addComponent(Camera3D);
        camera.perspective(60, Engine3D.aspect, 1, 5000.0);
        let controller = camera.object3D.addComponent(HoverCameraController);
        controller.setCamera(45, 0, 15);
        this.scene.addChild(cameraObj);
        // add an Atmospheric sky enviroment
        this.scene.addComponent(AtmosphericComponent).sunY = 0.6;
        // create a view with target scene and camera
        let view = new View3D();
        view.scene = this.scene;
        view.camera = camera;
        // start render
        Engine3D.startRenderView(view);
    }
}
new UserLogic().run();
ts
class PathAnimation extends ComponentBase {
    onUpdate() {
    // Update Position
    this.object3D.x = Math.sin(Time.time * 0.001) * 2;
    this.object3D.y = Math.cos(Time.time * 0.001) * 2;
  }
}

In this case, we change the Position property of the Object3D object, so that the object moves in a circular motion on the xy plane with time.

Released under the MIT License