如何清除 THREE.JS 场景

How do I clear THREE.JS Scene

我正在尝试寻找在不破坏场景本身的情况下清除场景中所有对象的方法。我知道命名对象是一种方式,然后当我们想要删除该对象时,我们只需 "get" 它的名称即可。但是,我想找到一种快速的方法来清除其中所有对象的场景,而不管它们的名称。有简单的方法吗?谢谢!

可以遍历场景的子物体,一个一个的移除

正如评论中所建议的那样,这应该以相反的顺序完成,以免修改您正在迭代的元素。

while(scene.children.length > 0){ 
    scene.remove(scene.children[0]); 
}

注意:这只是对象层次结构的一次快速而肮脏的清除。如果你打算经常这样做,你会冒 运行 上面的代码导致内存泄漏的风险,因为渲染器引用了对象的材质、纹理和几何图形。彻底清理现场更复杂,还有很多其他问题需要更详细地讨论:

我有一个更简洁的方法来做到这一点。我注意到 Object3D 的 remove 方法接受多个对象移除参数。这允许我们通过修改调用来使用整个 children 数组,以利用函数的内置 apply 方法将每个元素用作单独的参数。这就像这样:

scene.remove.apply(scene, scene.children);

遍历所有子对象并对它们的几何体、material 和纹理调用 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);

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);
    });
}