I\'m trying to do a Candy Crush-like map for my game in Unity, I\'m trying to gather all the buttons in an array and then set its onclick property so when I click on them I get
You've created a closure on a loop variable. A common pitfall, for sure. A suitable explanation and remedy for this kind of problem already exists on StackOverflow.
When you use the symbol i
, it is essentially a reference to the one and only i
that existed outside of your loop. Its value, by the time any of the listeners get invoked, will be the value it had at the end of the loop, which, in your case, would be the number of levels
you have.
To avoid this, you need to use the value of i
, not a reference to the variable. You can do this by creating a new variable that will have scope unique to one iteration of the loop and passing in that new variable's value. Basically a copy of i
is what you need.
The essence of the necessary change would be:
int i = 0;
foreach(GameObject level in levels)
{
int copy_of_i = i;
level.GetComponent<Button>().onClick.AddListener(() => SceneManager.LoadScene(copy_of_i + 1));
i++;
}
I think the problem is the lambda expression: () => SceneManager.LoadScene(i + 1)
you it is not the value of i, but instead the variable i, which will get incremented again over the other iterations so when you click on it SceneManager.LoadScene(i + 1); gets called, but i is now 25 or whatever your level number is.
Create a temporary variable directly before it so each lambda expression gets their own variable int tmp = i; level.GetComponent().onClick.AddListener(() =>SceneManager.LoadScene(tmp + 1));