Unity C#数组越界异常:二维数组存预制体网格实例化循环报错
嗨,我来帮你搞定这个数组越界的错误!这种IndexOutOfRangeException在Unity网格实例化场景里太常见了,基本都是循环索引和数组实际尺寸不匹配导致的,结合你的场景,我给你梳理几个排查和解决的方向:
1. 先检查循环的边界条件
数组的索引是从0开始的,这是最容易踩的坑!比如你定义的二维数组是3行×3列,那有效的索引是(0,0)到(2,2),如果循环里写了for (int i = 0; i <= 3; i++),那i=3的时候就会超出数组范围直接报错。
正确的写法应该是用<而不是<=,而且要基于数组的实际长度来写:
int rows = yourPrefabArray.GetLength(0); // 获取行数 int cols = yourPrefabArray.GetLength(1); // 获取列数 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 这里写实例化逻辑 } }
2. 确认数组的实际赋值情况
很多时候代码里定义的数组尺寸和Inspector面板里赋值的不一致!比如你代码里写了GameObject[,] prefabs = new GameObject[4,4];,但在Inspector里只给了3行预制体,那循环到第4行的时候就会找不到元素报错。
你可以加一行调试代码,打印数组的实际行列数,确认和你预期的一致:
Debug.Log($"数组实际行数:{yourPrefabArray.GetLength(0)},列数:{yourPrefabArray.GetLength(1)}");
3. 检查索引是否搞反了
有时候会不小心把行和列的索引写反,比如应该用yourPrefabArray[i,j],结果写成了yourPrefabArray[j,i]。如果数组的行和列长度不一样(比如4行×5列),那j到5的时候i的最大索引只有3,直接就越界了。
4. 结合层级面板的状态辅助排查
你提到层级面板能看到创建时的状态,比如如果已经实例化了一部分预制体才报错,那可以数一下实例化的数量:
- 如果实例化了8个就报错,那大概率是数组的某个维度长度是8(索引0-7),循环到第9次时索引超了;
- 或者看实例化的排列规律,是行排满了报错还是列排满了,能快速定位是哪个维度的索引出问题。
给你一个完整的正确示例代码
public GameObject[,] tilePrefabs; // 在Inspector里设置行列数并赋值预制体 public float gridSpacing = 1.5f; // 网格之间的间距 void Start() { int totalRows = tilePrefabs.GetLength(0); int totalCols = tilePrefabs.GetLength(1); for (int row = 0; row < totalRows; row++) { for (int col = 0; col < totalCols; col++) { // 先判断当前位置的预制体是否为空,避免空引用错误 if (tilePrefabs[row, col] != null) { // 计算网格位置,让预制体整齐排列 Vector3 spawnPosition = new Vector3(col * gridSpacing, 0, row * gridSpacing); // 实例化预制体 Instantiate(tilePrefabs[row, col], spawnPosition, Quaternion.identity); } else { Debug.LogWarning($"预制体数组[{row},{col}]位置没有赋值!"); } } } }
如果按照上面的方法还是没解决,你可以把代码里的数组定义和循环部分贴出来,或者详细描述下层级面板里实例化的状态(比如实例化了多少个就停了,有没有重复或者缺失的情况),我再帮你精准定位!
内容的提问来源于stack exchange,提问作者Yeikel

