- Home /
[Bug?] int parameter on dynamically added onClick-Event is wrong
Hey all,
I am making a shop where one can buy weapons. The UI-Buttons to buy the weapons are created dynamically.
If pressed, the button should call the function "BuyWeapon(i)" that gives the player the right weapon from a list, based on the parameter 'i' of the for-loop.
void Start(){
for(int i = 0; i < weapons.Count; i++){
Debug.Log(i);//returns i
//Instantiate button-prefab
GameObject go = Instantiate(Resources.Load("Button"),Vector3.zero,container.rotation) as GameObject;
//Add function BuyWeapon() to onClick of current button
UnityEngine.Events.UnityAction buy = () => { this.BuyWeapon(i); };//passes i as parameter
go.GetComponent<Button>().onClick.AddListener(buy);
}
}
public void BuyWeapon(int i){
Debug.Log(i);//returns always weapons.Count, not buttons' index-parameter
player.itemsList.Add(weapons[i]);
}
However, if I click any button, I will get an OutOfRange-Error on the function BuyWeapon() because the parameter 'i' on each onClick-event is equals "weapons.Count". But on Start() 'i' will return its value and so it should pass it to the AddFunction-Part.
This is paradox.
Thanks in advance.
Answer by Dave-Carlile · Apr 25, 2016 at 06:46 PM
Yes, it's a bug in your code. Your anonymous function is capturing the variable i, not the value of i. You must make a local copy of the variable i inside of the anonymous function. Otherwise you're just getting whatever the last value of i is.
e.g...
int localIndex = i;
buy = () => { this.BuyWeapon(localIndex); };
You can refer to this Stack Overflow question for more information.
Thank you so much! The localIndex-Variable had to be above this snippet to work, but now it works like a charm!
Yes, good catch! I edited the example accordingly.