Skip to content

自定义事件

除了基本的鼠标和键盘事件,引擎还提供了自定义事件 CEvent 类方便开发者使用,可以使用 Engine3D.inputSystem 触发和监听任意的自定义事件。我们推荐组件间需要交互时使用事件系统通信。

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

<
ts
import { Engine3D, Scene3D, Vector3, Object3D, Camera3D, View3D, AtmosphericComponent, LitMaterial, MeshRenderer, ComponentBase, CEvent, BoxGeometry, DirectLight } from '@orillusion/core';
import dat from 'dat.gui';

class UserEventScriptLeft extends ComponentBase {
    private rotation: number = 0;

    private OnRunEvent(e: CEvent) {
        console.log(e.type, e.data);
        let params = e.data;
        console.log(params);
        if (params.direction == 'left') {
            this.rotation = -5;
        } else if (params.direction == 'right') {
            this.rotation = 5;
        }
    }

    private OnStopEvent(e: CEvent) {
        console.log(e.type, e.data);
        this.rotation = 0;
    }

    public start() {
        Engine3D.inputSystem.addEventListener('RunEvent', this.OnRunEvent, this);
        Engine3D.inputSystem.addEventListener('StopEvent', this.OnStopEvent, this);
    }

    public onUpdate() {
        this.object3D.transform.rotationY += this.rotation;
    }
}

let scene: Scene3D;
let cameraObj: Object3D;
let camera: Camera3D;
let boxObj: Object3D;

await Engine3D.init();
scene = new Scene3D();
scene.addComponent(AtmosphericComponent);
cameraObj = new Object3D();
camera = cameraObj.addComponent(Camera3D);
camera.perspective(60, Engine3D.aspect, 1, 5000.0);
camera.lookAt(new Vector3(0, 5, 15), new Vector3(0, 0, 0));
scene.addChild(cameraObj);

// add a base light
let lightObj = new Object3D();
lightObj.addComponent(DirectLight);
scene.addChild(lightObj);

boxObj = new Object3D();
boxObj.addComponent(UserEventScriptLeft);
let mr: MeshRenderer = boxObj.addComponent(MeshRenderer);
mr.geometry = new BoxGeometry(3, 3, 3);
mr.material = new LitMaterial();
boxObj.localPosition = new Vector3(0, 0, 0);
scene.addChild(boxObj);

let view = new View3D();
view.scene = scene;
view.camera = camera;
// start render
Engine3D.startRenderView(view);

const gui = new dat.GUI();
// Debug
const debugInfo = {
    leftEvent: () => {
        let params = { direction: 'left' };
        let e = new CEvent('RunEvent', params);
        Engine3D.inputSystem.dispatchEvent(e);
    },
    rightEvent: () => {
        let params = { direction: 'right' };
        let e = new CEvent('RunEvent', params);
        Engine3D.inputSystem.dispatchEvent(e);
    },
    stopEvent: () => {
        let e = new CEvent('StopEvent');
        Engine3D.inputSystem.dispatchEvent(e);
    }
};
gui.add(debugInfo, 'leftEvent');
gui.add(debugInfo, 'rightEvent');
gui.add(debugInfo, 'stopEvent');

事件派发

调用 Engine3D.inputSystem.dispatchEvent 方法可以派发事件,派发对应事件会触发监听事件回调函数的执行。

ts
import {Engine3D, CEvent} from '@orillusion/core';

let customEvent = new CEvent("UserEvent", {name:'name',data:'data'});
Engine3D.inputSystem.dispatchEvent(customEvent);

事件监听

事件监听可以将事件与处理函数相关连

ts
// 监听事件
Engine3D.inputSystem.addEventListener("UserEvent", this.OnUserEvent, this);
// 处理函数
private OnUserEvent(e: CEvent) {
    let params = e.data;
}

移除事件

不再需要的事件可以移除

ts
Engine3D.inputSystem.removeEventListener("UserEvent", this.OnUserEvent, this);

CEvent

事件处理函数的参数是 CEvent 类型,从该参数获取事件信息

参数类型描述示例
typestring引擎中的事件的类型标识字符串"UserEvent"
dataany附加数据{ "name": "name", "data": "any" }