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