You need to enable JavaScript to run this app. Unity 遍历预制体数组按网格生成预览时出现重复实例问题
优惠活动
大模型
产品
解决方案
定价
更多

Unity 遍历预制体数组按网格生成预览时出现重复实例问题

建筑部件网格生成工具代码问题修正

问题根源

当前代码的职责分层完全错位,直接导致单个预制体被重复全网格生成:

  • 外层循环逐个取出预制体,每拿到一个就调用一次SpawnAssets方法
  • 但SpawnAssets方法内部嵌套了完整的网格遍历循环,会在调用时把当前传入的单个预制体,生成到网格的每一个位置
  • 最终结果:遍历第1个预制体时,把它放到所有网格位置;遍历第2个预制体时,再把第2个预制体放到所有网格位置。单个预制体被重复生成的次数,刚好等于网格总位置数,和你观察到的重复现象完全匹配。

你之前尝试把Instantiate语句移到嵌套循环外的操作没有达到预期,是因为这个修改是在单次SpawnAssets的作用域内完成的:此时只会生成1个预制体实例,后续循环仅持续修改这个实例的位置,最终实例会停在最后一个循环的坐标上,所有生成内容全部堆叠。

修正实现逻辑

需要彻底拆分两个独立职责:

  • 网格尺寸计算、坐标遍历只执行1次,和预制体数组的索引一一对应
  • 单个网格位置只生成1个对应索引的预制体实例,不要在单个预制体的生成逻辑里嵌套整套网格循环

修正后的可直接运行的代码:

// 计算可容纳所有预制体的正方形网格边长,避免空位置或位置不足
int gridSize = Mathf.CeilToInt(Mathf.Sqrt(allPrefabs.Count));
int prefabIndex = 0;

// 嵌套循环遍历所有网格坐标
for (int z = 0; z < gridSize; z++)
{
    for (int x = 0; x < gridSize; x++)
    {
        // 所有预制体生成完毕后提前终止循环
        if (prefabIndex >= allPrefabs.Count) break;

        // 取出当前索引对应的预制体,单次生成1个实例
        GameObject currentPrefab = allPrefabs[prefabIndex];
        GameObject assetClone = Instantiate(currentPrefab, Vector3.zero, Quaternion.identity);
        
        // 计算并设置当前网格位置
        Vector3 spawnPos = new Vector3(x * offsetDistance, 0, z * offsetDistance);
        assetClone.transform.position = spawnPos;
        assetClone.transform.parent = parentObj;

        // 索引递增,指向数组内的下一个预制体
        prefabIndex++;
    }
    // 内层循环触发终止条件时,同步终止外层循环
    if (prefabIndex >= allPrefabs.Count) break;
}

附带细节修正

  • 原代码中width = allPrefabs.Count/2的尺寸计算逻辑存在缺陷,整数除法会截断非整数值,导致网格总位置数和预制体数量不匹配
  • 原SpawnAssets方法开头的spawnPos = Vector3.zero全局变量赋值为冗余代码,实际生效的是方法内部定义的局部spawnPos变量,和全局变量无关联

内容的提问来源于stack exchange,提问作者Travis Mosier

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 21:36:07