- Home /
I have the following code, but when I try to open a level, it always tries to open level 25, which does not exist! Thanks in advance!,
void Start () { GetButtons (); LevelNaming (); }
private void GetButtons(){
LevelButtons = LevelMenuContent.GetComponentsInChildren<Button> ();
}
private void LevelNaming(){
for (int i = 0; i < LevelButtons.Length; i++) {
LevelName = LevelButtons [(i)].GetComponentInChildren<TextMeshProUGUI> ();
LevelName.text = (i + 1).ToString ();
//
//Onclick Listner
//
LevelButtons [i].onClick.AddListener (() => DoTaskOnClick (i + 1));
}
}
private void DoTaskOnClick(int ClickedButtonIndex){
SceneManager.LoadScene(ClickedButtonIndex);
}
private void LevelNaming(){
for (int i = 0; i < LevelButtons.Length; i++) {
LevelName = LevelButtons [(i)].GetComponentInChildren<TextMeshProUGUI> ();
LevelName.text = (i + 1).ToString ();
//
//Onclick Listner
//
LevelButtons [i].onClick.AddListener (() => DoTaskOnClick (i + 1));
}
}
private void DoTaskOnClick(int ClickedButtonIndex){
SceneManager.LoadScene(ClickedButtonIndex);
}
Answer by spencersteers · Mar 29, 2018 at 12:01 PM
So I learned something new!
Looks like the issue you are seeing is a nuance of how C# and closures behave together. Now I am no C# expect but basically the actual value of i that is passed into DoTaskOnClick (i + 1) isn't evaluated until the on click function gets called. At that point the loop is done and i has reached LevelButtons.Length so it is always sending 25 back.
From what I am reading you can get around this by declaring a local variable in the body of the for loop.
for (int i = 0; i < LevelButtons.Length; i++) {
int index = i;
LevelName = LevelButtons [(i)].GetComponentInChildren<TextMeshProUGUI> ();
LevelName.text = (index + 1).ToString ();
//
//Onclick Listner
//
LevelButtons [index].onClick.AddListener (() => DoTaskOnClick (index + 1));
}
This will effectively create a 'new' variable for each one of the click handlers. Hopefully that explanation isn't totally incorrect! I'm sure someone with more knowledge on the subject can correct me if I missed something.
For reference I ran into this stack overflow article which explains what is going on in more detail. https://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp
Your answer
Follow this Question
Related Questions
2d controll rigidboy.velocity.y 1 Answer
How to send PerRendererData to a CanvasRenderer 0 Answers
blend4web is better than unity WebGl ? 1 Answer
Unity 5 (All turns White) 0 Answers