You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 14:20:22