自定义事件
除了基本的鼠标和键盘事件,引擎还提供了自定义事件 CEvent 类方便开发者使用,可以使用 Engine3D.inputSystem
触发和监听任意的自定义事件。我们推荐组件间需要交互时使用事件系统通信。
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')
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);
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;
}
// 监听事件
Engine3D.inputSystem.addEventListener("UserEvent", this.OnUserEvent, this);
// 处理函数
private OnUserEvent(e: CEvent) {
let params = e.data;
}
移除事件
不再需要的事件可以移除
ts
Engine3D.inputSystem.removeEventListener("UserEvent", this.OnUserEvent, this);
Engine3D.inputSystem.removeEventListener("UserEvent", this.OnUserEvent, this);
CEvent
事件处理函数的参数是 CEvent 类型,从该参数获取事件信息
参数 | 类型 | 描述 | 示例 |
---|---|---|---|
type | string | 引擎中的事件的类型标识字符串 | "UserEvent" |
data | any | 附加数据 | { "name": "name", "data": "any" } |