Loop to create buttons and adding an onClick event not working right.

Hello, I am working on a character creator and I want to generate the selection by finding the objects in the resources folder. I am able to detect all of them properly, create every button I need and to parent them in a grid layout. The problem is that they dont do anything… So i heard about adding onClick events at runtime. This is what it looks like.

for (int hs = 0; Resources.Load("Hair/" + hs.ToString()) != null; hs++){
    GameObject selection = Instantiate (selectionButton);
	selection.transform.SetParent (GameObject.Find ("Hair Style").transform.GetChild (1).GetChild (0));
	selection.GetComponent<Button> ().onClick.AddListener (delegate {SetHairStyle(hs);});
}

The SetHairStyle function takes an int to find the object in the ressources folder. But it seems that it sends 4 instead of 0, 1, 2 and 3 when I click on the button… Why? What can i do to fix this? Thank you for your help.

This is just because of how closures work - the variable hs is not passed into the delegate by value as it is moved onto the heap by a compiler generated class. So, every time SetHairStyle is called, it looks up the variable hs, which was last set to 4. Instead, you need to create a local copy of the variable:

for (int hs = 0; Resources.Load("Hair/" + hs.ToString()) != null; hs++){
     GameObject selection = Instantiate (selectionButton);
     selection.transform.SetParent (GameObject.Find ("Hair Style").transform.GetChild (1).GetChild (0));
    int copy = hs;
     selection.GetComponent<Button> ().onClick.AddListener (delegate {SetHairStyle(copy);});
 }

This works because each execution of the loop is creating a new variable that is passed to the delegate - your original code was using the same variable.