我有一个游戏商店的脚本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;
}
}
}
对不起,如果这是一个菜鸟问题。如果你希望我再写一个脚本,我会的。此外,我将为您提供检查员或场景的图像或我将其添加到此帖子的内容。
答案 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
就是这样。