对象生命管理
动态创建出来的对象,不只是“创建并显示”这么纯粹,还要区分它们何时加入场景、何时移除、何时真正销毁。
四个核心动作
createXxx
js
const image = await api.createImage(arrayBuffer);createXxx()都属于对象创建。不同对象类型,API名称不一样。详细查看动态创建内容
add
把一个新创建的对象加入当前场景,使其可见:
js
await api.add(image);createXxx() API 返回对象后,并不会立即可见,所以都要调用一次 add()。
对象的visible属性也能控制可见性。使用api.setObjectVisible()。
remove
把对象从当前场景树中移除,但不会释放其底层资源,使其不可见:
js
await api.remove(image);意味着视频、动画等还可以继续播放,只是看不见而已。
适合做临时隐藏或重新挂接父子关系。
destroyObject
彻底销毁对象并释放资源:
js
await api.destroyObject(image);一旦销毁,之前保存的句柄对象就不能继续使用,建议立即移除对象句柄,避免继续引用。
remove 和 destroyObject 的区别
| 方法 | 是否从场景消失 | 是否释放资源 | 是否还能再次 add |
|---|---|---|---|
remove() | 是 | 否 | 能 |
destroyObject() | 是 | 是 | 不能 |
如果你后面还打算继续使用这个对象,优先 remove();如果已经确定不会使用,则用 destroyObject()。
clear
清空并销毁当前场景的所有对象:
js
await api.clear();一般情况下不使用,非常危险的操作。会导致获取的所有对象句柄都失效。
如果只想销毁动态创建出来的对象,则需要用户自己储存对象列表,并在需要销毁时,再进行remove/destroyObject。
一个简单的宿主层封装
js
let dynamicObjects = [];
async function addObject(handle) {
await api.add(handle);
dynamicObjects.push(handle);
}
async function removeObject(handle) {
await api.remove(handle);
dynamicObjects = dynamicObjects.filter(o => o !== handle);
}
async function destroyAllDynamicObjects() {
while (dynamicObjects.length) {
const handle = dynamicObjects.pop();
await api.remove(handle);
await api.destroyObject(handle);
}
}推荐清理时机
页面销毁
当宿主页面本身要卸载时:
- 先清理你注册过的对象事件
- 再销毁动态对象
- 最后关闭 iframe
场景切换
如果你是“同一个 iframe 中重复打开不同 sceneId”:
- 不要复用旧场景中的对象句柄
- 不要复用旧场景中的高级api对象
父子关系管理
添加子对象
js
const group = await api.createGroup();
const image = await api.createImage(arrayBuffer);
await api.add(group);
// 将image添加到group的子列表中。
// 因为group已在上一步进入场景树,所以image不需要再调用api.add。
await api.addChild(group, image);任何3D对象,都可以增加子对象。
包括camera、图片、视频、模型等。
音频不属于3D对象,就不能增加。
移除子对象
js
await api.removeChild(group, image);获取子对象列表
js
const children = await api.getChildren(obj); // 输出Array