首页 > 解决方案 > 从场景中移除所有对象的正确方法

问题描述

我知道有很多 SO 问题询问有关从场景中删除所有内容的类似问题,但是我尝试过的所有内容都没有按我希望的方式工作。似乎也没有明确的方法可以从场景中删除所有内容(在文档或类似的内容中),所以我希望有人能告诉我正确的方法。

以下是我目前用于从场景中删除所有内容的功能:

function removeAll() {
    while (scene.children.length > 0) {
        scene.remove(scene.children[0]);
        if (scene.children[0] == THREE.Mesh || scene.children[0] == THREE.Object3D || scene.children[0] == THREE.Group) {
            scene.children[0].dispose();
            scene.children[0].geometry.dispose();
            scene.children[0].material.dispose();
        }
    }
}

这可以正常工作,并且似乎在视觉上从场景中删除了所有内容。

我的问题是,如果我调用此函数,然后重新调用创建场景的函数或创建新场景的函数(请参阅上下文部分,我有多个),场景中的对象比之后的要多第一次调用场景创建函数 ( ) -在控制台中init()选中。renderer.info

我还注意到,在调用该removeAll()函数然后重新加载场景之后,我这样做的次数越多,场景变得越迟钝,我认为这是因为并非所有内容都被正确删除。

所以我问:

从场景中删除所有内容的正确方法是什么。

对于上下文:

我有一个 HTML 菜单,用户可以在其中选择他们想要“跳过”到的场景。当他们这样做时,我需要删除所有内容,然后仅重新加载该特定场景的对象。我拥有所有这些功能,唯一的问题是在新场景加载之前移除对象。

标签: javascriptthree.js

解决方案


我看到的最重要的事情是你只处理顶级场景的孩子。如果这些对象本身有孩子,那么它们不一定被妥善处理。

老实说,确保您清理所有内容的最佳方法就是处理渲染器并制作一个新渲染器并转储场景并让它被 GCed。

如果您想坚持尝试使用一种方法来清除所有内容,那么您需要递归到孩子中并处理他们可能拥有的任何几何形状、材料和纹理。

你可以在这篇相关文章中找到一个非常全面的 dispose 函数。我要做的唯一更改是修改diposeHierarchy以将对象彼此分离,如下所示:

function disposeHierarchy (node, callback)
{
    for (var i = node.children.length - 1; i >= 0; i--)
    {
        var child = node.children[i];
        disposeHierarchy (child, callback);
        callback (child);
        node.remove(child);
    }
}

推荐阅读