I have a script Shop.cs
for an in-game shop. I get this weird error when I click the button. It says:
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 and Weapons are the same length.
Here is 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;
}
}
}
I'm sorry if this is a noob question. If you would like me to put another script, I will. Also I will give you images of the inspector or the scene or something I'll add it to this post.
Could be caused by the variables not being captured. See the great answer here for more information: Using the iterator variable of foreach loop in a lambda expression - why fails?
Basically, since you just have a reference to your index variable, when it gets updated to 2 in your for loop, 2 is the value returned when your delegate is called. btn[2] is out of range.
You should be able to just do this:
int capturedIndex = i;
BoughtSomething(weapons[capturedIndex], btns[capturedIndex]);