Three.js Group子对象无法访问:为何_activeObjects.children为空?
Three.js GameManager子对象丢失问题分析与解决
问题代码
GameManager类
class GameManager { constructor() { this._activeObjects = new THREE.Group(); } get randomGeometry() { const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1); return geometry; } get randomMaterial() { const material = new THREE.MeshBasicMaterial({ color: "red", wireframe: true, }); return material; } spawnCube(scene) { const newCube = new THREE.Mesh(this.randomGeometry, this.randomMaterial); this._activeObjects.add(newCube); scene.add(newCube); } animateObjects() { this._activeObjects.children.forEach((obj) => { obj.position.z += 1; }); } } export const gameManger = new GameManager();
渲染动画代码
gameManger.spawnCube(scene); (function animate() { gameManger.animateObjects(); renderer.render(scene, camera); requestAnimationFrame(animate); })();
问题描述
立方体可正常渲染,但仅在spawnCube方法作用域内,_activeObjects.children包含添加的立方体;调用animateObjects方法时,该数组为空。疑惑同一个Group引用为何无法保留子对象。
原因分析
Three.js中一个Object3D(包括Mesh)只能属于一个父对象。当你先执行this._activeObjects.add(newCube)把立方体加到Group里,紧接着又执行scene.add(newCube)时,Three.js会自动将这个立方体从之前的父对象(_activeObjects)中移除,导致_activeObjects.children变为空数组。
解决方案
有两种可行的解决方式:
方案1:将Group整体加入场景
把_activeObjects这个Group直接添加到场景中,所有立方体只加入Group,不再单独加入场景:
// 初始化时将Group添加到场景(比如GameManager实例化后) scene.add(gameManger._activeObjects); // 修改GameManager的spawnCube方法 spawnCube() { const newCube = new THREE.Mesh(this.randomGeometry, this.randomMaterial); this._activeObjects.add(newCube); // 移除scene.add(newCube)这一行 }
这样所有立方体都归属于_activeObjects组,同时该组在场景中,既能正常渲染,也能通过Group统一控制动画。
方案2:用数组存储活跃对象
如果需要单独管理立方体同时让它们直接属于场景,可以将_activeObjects改为数组而非Three.js Group:
// 修改GameManager构造函数 constructor() { this._activeObjects = []; // 用数组替代Group } // 修改spawnCube方法 spawnCube(scene) { const newCube = new THREE.Mesh(this.randomGeometry, this.randomMaterial); this._activeObjects.push(newCube); scene.add(newCube); } // animateObjects遍历数组即可 animateObjects() { this._activeObjects.forEach((obj) => { obj.position.z += 1; }); }
内容的提问来源于stack exchange,提问作者Preston Bourne
相关产品推荐
相关产品推荐

