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
就是这样。
我有一个游戏内商店脚本 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
就是这样。