4.6 UI callback variable

I’m creating buttons using a prefab and instantiate it by code.
I’m then trying to get each button to print their own number on click.
Right now, each button is only returning the same number “5”.
Is there an easy way to do that ?

Here is the code


using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class TESTGUI : MonoBehaviour {

	public Canvas myCanvas;
	public Button buttonPrefab;

	private void printNumber(int myNumber)
	{
		Debug.Log (myNumber);
	}

	// Use this for initialization
	void Start () {
		for(int i=0; i<5; i++)
		{
			Button myButton = Instantiate(buttonPrefab) as Button;
			myButton.transform.SetParent(myCanvas.transform, false);
			myButton.transform.position = new Vector3(250f, 50f + (40f * i), 0f);
			myButton.onClick.AddListener(() => printNumber(i));
		}
	}
}

You’re setting a lambda function for the onClick event, that function will “know” the value of “i” when you click the button, not when the function is added, and the value will be the value of the “i” variable of the for loop (lambda functions “remember” the context when they where declared).

Since the loop finishes before you can click the buttons, the value of “i” is 5 (the loops goes from i = 0 to i = 4, and it “breaks” once i reaches 5).

The solution is to use another variable that’s specific to each iteration instead of the more “global” i variable which is incremented. Replace the last line inside the for loop with this 2 lines:

int j = i;
myButton.onClick.AddListener(() => printNumber(j));

This way, for each button, the “j” they know is a different variable from the “j” of the rest.