Unity中GameObject列表/数组出现意外IndexOutOfBoundsError问题
问题描述
运行以下代码时抛出IndexOutOfBoundsError,但调试时出现矛盾现象:打印weapons列表显示为空数组[],但访问weapons[0].name却能返回正确名称;切换数组与列表类型后问题仍存在。
相关代码:
public void SwitchWeapon(int index) { Debug.Log(index); foreach(GameObject weapon in weapons) { weapon.GetComponent<Renderer>().enabled = false; } pc.weapon = weapons[0]; weapons[index].GetComponent<Renderer>().enabled = true; }
问题分析与解决
核心矛盾解析
打印weapons显示为空但能访问weapons[0],大概率是Unity序列化/调试显示延迟导致的:
- Unity Inspector中的列表可能未完成序列化,调试打印时显示为空,但实际内存中已有元素;
- 或是调试打印的是变量旧的空引用,但代码执行时用的是已赋值的新引用。
代码中的直接问题
- 无边界检查:直接访问
weapons[0]和weapons[index],未判断列表是否为空、index是否合法,一旦不满足条件就会触发索引越界错误; - 逻辑错误:代码本意是切换到
index对应的武器,却错误地将pc.weapon固定设为weapons[0],不符合需求。
修复后的代码
public void SwitchWeapon(int index) { Debug.Log(index); // 边界检查,提前拦截非法情况 if(weapons == null || weapons.Count == 0 || index < 0 || index >= weapons.Count) { Debug.LogError("武器列表为空或索引非法"); return; } // 隐藏所有武器,添加组件空判断避免报错 foreach(GameObject weapon in weapons) { Renderer renderer = weapon.GetComponent<Renderer>(); if(renderer != null) renderer.enabled = false; } // 切换到目标武器 pc.weapon = weapons[index]; Renderer targetRenderer = weapons[index].GetComponent<Renderer>(); if(targetRenderer != null) targetRenderer.enabled = true; }
额外排查建议
- 确认
weapons的赋值时机:要在调用SwitchWeapon之前完成初始化(比如在Awake或Start方法中),避免异步赋值导致的访问时机问题; - 检查Unity Inspector:如果
weapons是序列化的公共变量,确认已拖入对应武器对象;若调试显示异常,重启Unity编辑器可解决多数序列化显示问题。
内容的提问来源于stack exchange,提问作者domuno
相关产品推荐
相关产品推荐

