Skip to content
本页内容

自定义事件

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


Orillusion powered by WebGPU on Chrome/Edge 113+
Please upgrade to latest Chrome/Edge

<
ts
import { Engine3D, Scene3D, Vector3, Object3D, Camera3D, ForwardRenderJob, LitMaterial, MeshRenderer, ComponentBase, CEvent, BoxGeometry } from "@orillusion/core";
import dat from 'https://cdn.skypack.dev/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
    }

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

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

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

async function init() {
    await Engine3D.init({});
    // 创建场景实例
    scene = new Scene3D();
    // 创建相机实例
    cameraObj = new Object3D();
    camera = cameraObj.addComponent(Camera3D);
    // 设置正交相机
    camera.perspective(60, window.innerWidth / window.innerHeight, 1, 5000.0);
    camera.lookAt(new Vector3(0, 5, 15), new Vector3(0, 0, 0));
    // 设置主相机
    scene.addChild(cameraObj);

    // 添加物体
    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 renderJob = new ForwardRenderJob(scene);
    // 开始执行渲染
    Engine3D.startRender(renderJob);
}


async function addGui() {
    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");
}

async function demo() {
    await init();
    addGui();
}

demo();

事件派发

调用 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" }