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

Three.js技术问题:如何用scene.getObjectByName()移除OBJ模型

城市场景批量建筑生成实现方案

我最近在开发游戏城市场景时,摸索出一套批量生成并排布建筑的流程,分享给大家参考:

1. 加载基础建筑模型

首先用OBJLoader和MTLLoader加载了4种不同的建筑基础模型,确保每个模型都正确关联了材质(这里以Three.js为例):

// 先初始化加载器并加载MTL材质
const mtlLoader = new MTLLoader();
const baseBuildings = [];

// 循环加载4组OBJ+MTL模型
for (let i = 1; i <= 4; i++) {
  mtlLoader.load(`building${i}.mtl`, (materials) => {
    materials.preload();
    const objLoader = new OBJLoader();
    objLoader.setMaterials(materials);
    objLoader.load(`building${i}.obj`, (mesh) => {
      // 可以提前对基础模型做缩放、原点校准等预处理
      mesh.scale.setScalar(1.2);
      baseBuildings.push(mesh);
      // 所有基础模型加载完成后再执行后续逻辑
      if (baseBuildings.length === 4) {
        cloneAndArrange();
      }
    });
  });
}

2. 批量克隆模型并统一存储

等4个基础模型全部加载完成后,通过for循环给每个模型克隆15份,把所有克隆体存入masterBuildingArray数组:

const masterBuildingArray = [];

function cloneAndArrange() {
  baseBuildings.forEach(base => {
    for (let i = 0; i < 15; i++) {
      const clone = base.clone();
      // 给每个克隆体加随机缩放,避免完全重复
      clone.scale.setScalar(Math.random() * 0.4 + 0.9);
      masterBuildingArray.push(clone);
    }
  });
  // 克隆完成后打乱数组顺序
  shuffleArray(masterBuildingArray);
  // 开始按规则排布建筑
  placeBuildings();
}

3. 随机打乱建筑数组

用Fisher-Yates洗牌算法打乱数组,让建筑排布更自然,避免同类型建筑扎堆:

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

4. 按规则排布建筑到道路两侧

通过forEach遍历数组,结合索引判断,每10个建筑为一组,排列在道路两侧形成3行:

function placeBuildings() {
  const roadWidth = 25;  // 场景内道路的宽度
  const rowGap = 35;     // 行与行之间的纵向间距
  const colGap = 18;     // 同列建筑的横向间距

  masterBuildingArray.forEach((building, index) => {
    const groupNum = Math.floor(index / 10);
    const posInGroup = index % 10;

    // 只处理前3组(对应3行)
    if (groupNum < 3) {
      let xPos, zPos;
      // 组内前5个放道路左侧,后5个放右侧
      if (posInGroup < 5) {
        xPos = -roadWidth/2 - colGap*(posInGroup + 1);
      } else {
        xPos = roadWidth/2 + colGap*(posInGroup - 4);
      }
      // 设置纵向行位置
      zPos = -groupNum * rowGap;

      building.position.set(xPos, 0, zPos);
      scene.add(building);
    }
  });
}

这套流程的核心是先批量生成足够的建筑克隆体,通过洗牌打破重复感,再按分组规则把建筑有序排布到道路两侧,生成的场景既有秩序感又不会显得单调。

内容的提问来源于stack exchange,提问作者JJ Gerrish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:20:12