我无法解决的Unity IndexOutOfRangeException

时间:2016-04-13 23:32:13

标签: c# unity3d indexoutofrangeexception

我有一个游戏商店的脚本Shop.cs。单击按钮时出现这个奇怪的错误。它说:

IndexOutOfRangeException: Array index is out of range.
Shop+<Start>c__AnonStorey1.<>m__9 () (at Assets/Scripts/Menu/Shop.cs:24)
UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:144)
UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:621)
UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:756)
UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
UnityEngine.EventSystems.EventSystem:Update()

Btns和Weapons的长度相同 这是Shop.cs

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

public class Shop : MonoBehaviour {

    public Button[] btns;
    public int money;
    public Weapon[] weapons;

    public int weaponLength;

    void Start()
    {

        weapons = new Weapon[weaponLength];

        AddWeaponsToArray();

        for(int i = 0; i < btns.Length; i++)
        {
            btns[i].onClick.AddListener(delegate ()
            {
                if (weapons[i] == null)
                    Debug.LogError("Not enough wpns!!!");
                else
                    BoughtSomething(weapons[i], btns[i]);
            });
        }


    }

    void Update()
    {
        for (int i = 0; i < weapons.Length; i++)
        {
            Weapon _wpn = weapons[i];
            if (!_wpn.purchased)
                _wpn.active = false;
            if (_wpn.active)
                btns[i].enabled = false;
            if (!_wpn.purchased && _wpn.cost > money)
                btns[i].enabled = false;
        }
    }

    void AddWeaponsToArray()
    {
        weapons[0] = CreateWeapon.newWeapon("Roto", 1, 100, 0.5f, 50, 100, false, false);
    }

    void BoughtSomething(Weapon _wpn, Button _btn)
    {
        if (_wpn.purchased)
        {
            _wpn.active = true;
        }
        else
        {
            money -= _wpn.cost;
            _wpn.purchased = true;
            _wpn.active = true;
        }
    }

}

对不起,如果这是一个菜鸟问题。如果你希望我再写一个脚本,我会的。此外,我将为您提供检查员或场景的图像或我将其添加到此帖子的内容。

enter image description here

3 个答案:

答案 0 :(得分:1)

可能是由未捕获的变量引起的。有关详细信息,请参阅此处的精彩答案:Using the iterator variable of foreach loop in a lambda expression - why fails?

基本上,由于您只是对索引变量的引用,当它在for循环中更新为2时,2是调用委托时返回的值。 btn [2]超出范围。

你应该能够做到这一点:

int capturedIndex = i;
BoughtSomething(weapons[capturedIndex], btns[capturedIndex]);

答案 1 :(得分:0)

我的猜测是它在这里。见评论。

    for(int i = 0; i < btns.Length; i++)
    {
        btns[i].onClick.AddListener(delegate ()
        {
            // Are btns & weapons the same length?
            BoughtSomething(weapons[i], btns[i]);
        });
    }

//Safer
for(int i = 0; i < btns.Length && i < weapons.Length; i++) {
  var btn = btns[i];
  var weapon = weapons[i];
  if(btn == null || weapon == null) continue;
  btn.onClick.AddListener(delegate() {
      BoughtSomething(weapon, btn);
  });
}

答案 2 :(得分:0)

您可以尝试转到“构建设置”(在“文件”->“构建设置”中,或单击(Ctrl + Shift + B)],然后单击“播放器设置”(也可以从“编辑”->“项目设置”->“播放器”中访问),并在检查器中在窗口中选择其他设置。在“渲染”下,查看是否选中了以下选项:

Auto Graphics API

Multithreaded Rendering

Static Batching

Dynamic Batching

Lightmap Streaming Enabled

就是这样。