unity IndexOutOfRangeException 我解决不了

Unity IndexOutOfRangeException that I can't solve

我有一个游戏内商店脚本 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;
        }
    }

}

如果这是一个菜鸟问题,我很抱歉。如果你想让我放另一个剧本,我会的。另外,我会给你检查员或场景的图像,或者我会把它添加到这个 post。

我猜它就在这里。见评论。

    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);
  });
}

可能是变量没有被捕获导致的。有关详细信息,请参阅此处的最佳答案: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]);

您可以尝试转到构建设置 [在文件->构建设置或点击 (Ctrl+Shift+B)] 并单击播放器设置(也可以从编辑->项目设置->播放器访问)并在Inspector window select 其他设置。在渲染下查看是否选中了以下选项:

Auto Graphics API

Multithreaded Rendering

Static Batching

Dynamic Batching

Lightmap Streaming Enabled

就是这样。