Object3D
Object3D
是引擎内置的实体对象,通常被当做基本的组件容器,可以通过不同组件组合来实现不同的功能。
Object3D
默认自带了 Transform 组件,在没有其它组件时,只保留基础的容器能力,可以被当做父节点添加或组合其它的 Object3D
。
Object3D
提供了一系列方法,可以方便添加或者查找子对象以及子对象所附加的组件信息,还可以通过代码的方式和其它组件建立连接。
节点状态
初始化一个 Object3D
对象之后,默认处于显示状态,通过设置 transform.enable
的属性变更节点的状态,如果设置为 false
,这将停用该节点对象以及该节点下所有的子节点对象,同时附加在这些节点之上的所有组件也将停止调用。
let obj = new Object3D();
obj.transform.enable = false; //隐藏节点及其所有子节点
节点的添加和移除
添加一个子节点,可以使用 addChild 方法
移除一个子节点,可以使用 removeChild 方法
移除特定位置子节点,可以使用 removeChildByIndex 方法
从父级移除自己,可以使用 removeFromParent 方法
移除所有子节点,可以使用 removeAllChild 方法
let parent = new Object3D();
let child = new Object3D();
//添加节点
parent.addChild(child);
//移除节点
parent.removeChild(child);
//or 子节点自己删除
child.removeFromParent();
//or 移除所有子节点
parent.removeAllChild();
添加和移除组件
通过 Object3D
自带的 addComponent 和 removeComponent 方法,可以方便的在运行时添加和移除组件。
let obj = new Object3D();
//为节点添加平行光组件
let dl = obj.addComponent(DirectLight);
//移除组件
obj.removeComponent(DirectLight);
获取组件节点
所有的组件都是继承于 ComponentBase
,在组件内部可以通过 this.object3D
属性获得当前组件所属的节点。
//自定义一个组件,效果是把节点的X轴位置增加10
class CustomComponent extends ComponentBase {
public start() {
this.object3D.x += 10;
}
}
获取节点的其它组件
通过 Object3D
自带的 getComponent 方法,可以方便的获取节点上的组件。
//自定义一个组件,效果是变更节点上的另一个灯光组件,改变灯光的颜色
class CustomComponent extends ComponentBase {
public start() {
let light = this.object3D.getComponent(DirectLight)
light.lightColor = new Color(1, 0, 0);
}
}
let obj = new Object3D();
obj.addComponent(DirectLight);
obj.addComponent(CustomComponent);
查找子节点
通过方法 getChildByIndex 可以按子节点层级顺序来获取子节点
通过方法 getChildByName 可以在知道子节点名称的情况下获取子节点
遍历所有子节点
我们可以通过 forChild 遍历当前节点下的所有节点,包括子节点的子节点,通过回调函数完成具体操作。
// 遍历所有子节点,执行回调
parent.forChild((child)=>{
// 具体操作逻辑
})
释放节点资源
通过方法 destroy 可以释放当前节点的资源,包括对象本身和对象加载的所有组件。但默认情况下,渲染组件所需的材质、几何体以及贴图资源不会随着节点一起释放,因为多个物体可能正在共享同一个材质和几何体,或者未来场景需要使用到这些资源。如果想要释放所有资源,一般需要手动释放渲染对象。
// 创建对象
let obj = new Object3D();
//为节点添加渲染组件
let mr = obj.addComponent(MeshRenderer)
let geometry = mr.geometry = new BoxGeometry()
let material = mr.material = new LitMaterial()
// 销毁对象,释放内存
obj.destroy() // 但不会释放 geometry 和 material
geometry.destroy() // 手动释放几何资源
material.destroy() // 手动释放材质资源
如果确定节点资源不再使用,可以使用 destroy(true)
附加参数来强制销毁节点的所有相关资源。
TIP
如果渲染对象正在被共享使用,强制删除可能会触发引擎错误,导致渲染无法继续
let obj1 = new Object3D();
let obj2 = new Object3D();
// 创建几何体和材质
let metry = new BoxGeometry()
let material = new LitMaterial()
// 为节点添加渲染组件, 共享几何体和材质信息
let mr1 = obj1.addComponent(MeshRenderer)
let mr2 = obj2.addComponent(MeshRenderer)
mr1.geometry = mr2.geometry = geometry
mr2.material = mr2.material = material
// 若强制销毁其中一个,会触发引擎报错,渲染无法继续
obj1.detroy(true) // 会强制释放 geometry 和 material
更多详细用法请参看 Object3D API