我正在尝试找到一种在不销毁场景本身的情况下清除场景中所有对象的方法。我知道给对象命名是一种方法,然后当我们想要删除该对象时,只需通过名称“获取”它即可。但是,我希望找到一种快速清除场景中所有对象的方法,而不管它们的名称如何。有简单的方法吗?谢谢!
我正在寻求在不破坏场景本身的情况下清除场景中所有对象的方法。尽管我知道可以通过为对象命名来实现此目的,然后在需要删除对象时使用其名称。但是,我想找到一种更快速的方法,可清除场景中所有对象,而不考虑它们的名称。是否有这样的方法呢?谢谢!我正在尝试找到一种在不销毁场景本身的情况下清除场景中所有对象的方法。我知道给对象命名是一种方法,然后当我们想要删除该对象时,只需通过名称“获取”它即可。但是,我希望找到一种快速清除场景中所有对象的方法,而不管它们的名称如何。有简单的方法吗?谢谢!
我正在寻求在不破坏场景本身的情况下清除场景中所有对象的方法。尽管我知道可以通过为对象命名来实现此目的,然后在需要删除对象时使用其名称。但是,我想找到一种更快速的方法,可清除场景中所有对象,而不考虑它们的名称。是否有这样的方法呢?谢谢!您可以遍历场景的子对象并逐个删除它们。
正如评论中建议的那样,应该按相反的顺序进行操作,以免修改您正在迭代的元素。
while(scene.children.length > 0){
scene.remove(scene.children[0]);
}
注意:这只是一个快速而简单的对象层次清理。如果您打算经常这样做,由于渲染器对对象材质、纹理和几何体有引用,因此使用上述代码会导致内存泄漏的风险。完整场景的清理更加复杂,并且还有许多其他问题需要详细了解:我有一种更简洁的做法。我注意到Object3D
的remove
方法接受多个参数以进行对象移除。这使我们可以通过修改调用以将每个元素作为单独的参数使用来使用整个children
数组,从而利用函数的内置apply
方法。操作如下:
scene.remove.apply(scene, scene.children);
遍历所有的子元素并调用其几何、材质和纹理的dispose方法。以下是我的解决方案。
function clearThree(obj){
while(obj.children.length > 0){
clearThree(obj.children[0]);
obj.remove(obj.children[0]);
}
if(obj.geometry) obj.geometry.dispose();
if(obj.material){
//in case of map, bumpMap, normalMap, envMap ...
Object.keys(obj.material).forEach(prop => {
if(!obj.material[prop])
return;
if(obj.material[prop] !== null && typeof obj.material[prop].dispose === 'function')
obj.material[prop].dispose();
})
obj.material.dispose();
}
}
clearThree(scene);
obj.material [prop]
为空,那么它将被 if(!obj.material [prop])
检查捕获(因为null是falsy值)。实际上,以前的 if/return 可以被移除,并且obj.material [prop]!== null
可以缩短为obj.material [prop]
以高效地处理所有情况。 - Jonathan Grayconst n = scene.children.length - 1;
for (var i = n; i > -1; i--) {
scene.remove(scene.children[i]);
}
在逆序迭代项目时,不会出现当前数组索引的问题。
一定要删除所有东西,特别是纹理贴图。
function removeObjectsWithChildren(obj){
if(obj.children.length > 0){
for (var x = obj.children.length - 1; x>=0; x--){
removeObjectsWithChildren( obj.children[x]);
}
}
if (obj.geometry) {
obj.geometry.dispose();
}
if (obj.material) {
if (obj.material.length) {
for (let i = 0; i < obj.material.length; ++i) {
if (obj.material[i].map) obj.material[i].map.dispose();
if (obj.material[i].lightMap) obj.material[i].lightMap.dispose();
if (obj.material[i].bumpMap) obj.material[i].bumpMap.dispose();
if (obj.material[i].normalMap) obj.material[i].normalMap.dispose();
if (obj.material[i].specularMap) obj.material[i].specularMap.dispose();
if (obj.material[i].envMap) obj.material[i].envMap.dispose();
obj.material[i].dispose()
}
}
else {
if (obj.material.map) obj.material.map.dispose();
if (obj.material.lightMap) obj.material.lightMap.dispose();
if (obj.material.bumpMap) obj.material.bumpMap.dispose();
if (obj.material.normalMap) obj.material.normalMap.dispose();
if (obj.material.specularMap) obj.material.specularMap.dispose();
if (obj.material.envMap) obj.material.envMap.dispose();
obj.material.dispose();
}
}
obj.removeFromParent();
return true;
}
你需要使用scene.clear()。这里是示例代码,首先将其变成一个函数,然后每次想要更改对象时调用该函数。
function loadscene(path)
{
scene.clear();
loader.load(path,function(gltf)
{
const model = gltf.scene;
model.position.set(0,0,0);
model.rotation.set(0,0,0);
model.scale.set(1,1,1);
scene.add(model);
animate();
},
undefined, function(e)
{
console.error(e);
});
}
scene.remove(scene.children[0]); }```
- Alleo