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

Unity游戏ArgumentOutOfRangeException异常排查求助

解决Unity中设置菜单外星人名称时的ArgumentOutOfRangeException异常

我来帮你排查这个问题,这个异常的核心原因是列表索引越界,咱们一步步拆解分析:

异常根源分析

先看你的菜单赋值代码里的循环:

for (int buttonIndex = monsterButtons.Count; buttonIndex > 0; buttonIndex--) {
    monsterButtons [buttonIndex].GetComponentInChildren<Text> ().text = BestiariumData.scannedSpecies [buttonIndex].name;
}

这里有两个明显的问题:

  1. 循环起始索引错误:List的索引是从0开始的,最大有效索引是Count - 1。你用monsterButtons.Count作为起始值,比如按钮列表有3个元素,Count是3,直接访问monsterButtons[3]就会超出范围。
  2. 未校验两个列表的数量匹配:scannedSpecies的元素数量可能少于monsterButtons的数量,当buttonIndex超过scannedSpecies.Count - 1时,访问scannedSpecies[buttonIndex]也会触发越界异常。

另外,你的BestiariumData里用单独的dnaBar_1到dnaBar_8来存储进度,这种写法不仅冗余,还很容易和scannedSpecies的元素对应不上,进一步加剧索引问题。

解决方案

1. 修复菜单赋值的循环逻辑

把循环改成从0开始遍历,同时增加索引有效性校验,避免越界:

public List<GameObject> monsterButtons = new List<GameObject>();
public static bool nameButtons = false;

void LateUpdate () {
    if (nameButtons) {
        // 正向遍历按钮列表,索引从0到Count-1
        for (int buttonIndex = 0; buttonIndex < monsterButtons.Count; buttonIndex++) {
            Text buttonText = monsterButtons[buttonIndex].GetComponentInChildren<Text>();
            // 先检查scannedSpecies是否有对应索引的元素
            if (buttonIndex < BestiariumData.scannedSpecies.Count) {
                buttonText.text = BestiariumData.scannedSpecies[buttonIndex].name;
                // 如果要显示DNA进度,可以同步取对应的savedDNAFillRates值
                // 比如:buttonProgress.fillAmount = BestiariumData.savedDNAFillRates[buttonIndex];
            } else {
                // 没有对应扫描物种时显示默认文本
                buttonText.text = "未扫描";
            }
        }
    }
}

2. 优化BestiariumData的数据结构

把单独的dnaBar_1到dnaBar_8替换成与scannedSpecies对应的列表,这样每个扫描的物种都有对应的DNA进度,避免索引混乱:

public static List<GameObject> scannedSpecies = new List<GameObject>();
public static List<float> savedDNAFillRates = new List<float>();

// 删除原来的dnaBar_1到dnaBar_8字段

3. 修正射线扫描的存储逻辑

在扫描完成添加物种时,同步把DNA进度加入savedDNAFillRates,后续更新进度时也通过索引对应:

else if (dna_percent_0_to_1 >= 1) {
    EnemyAI enemyAI = hitInfo.collider.gameObject.GetComponent<EnemyAI>();
    if (enemyAI.raceIndex == 1) {
        if (!raceOneWasAdded) {
            BestiariumData.scannedSpecies.Add(hitInfo.collider.gameObject);
            // 添加初始DNA进度(你原来的0.25f)
            BestiariumData.savedDNAFillRates.Add(0.25f);
            raceOneWasAdded = true;
        } else {
            // 找到对应物种的索引,更新进度
            int targetIndex = BestiariumData.scannedSpecies.FindIndex(obj => obj.GetComponent<EnemyAI>().raceIndex == 1);
            if (targetIndex != -1) {
                BestiariumData.savedDNAFillRates[targetIndex] += 0.25f;
                // 确保进度不超过100%
                BestiariumData.savedDNAFillRates[targetIndex] = Mathf.Min(BestiariumData.savedDNAFillRates[targetIndex], 1f);
            }
        }
    }
    // 重置扫描进度
    dna_percent_0_to_1 = 0f;
    dna_collect_circle.fillAmount = 0f;
    enemyAI.dna_collected = true;
}

额外建议

  • 尽量用foreach遍历列表(如果不需要索引的话),可以减少手动处理索引的错误。
  • 对List的访问操作,最好都加上if (index >=0 && index < list.Count)的校验,尤其是在动态添加/删除元素的场景下。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:37:23