Passing a temporary variable to add listener

Hi I am trying to pass a method to an add listener when the button is clicked. First I instantiated the object and assign a parent for it. Then I add a listener to the object. The problem is that the only way I know how to pass a method with parameter in the add listener event of unity is through lambda expression. So when I click the button it always passes the last item I iterated to.

Here is a snippet of my code:

 foreach(CardData cardItem in p_cards)
			{
				if(cardItem.Type == CardType.Normal)
				{
					if(count == 0)
					{
						cardItem.Name = "CARD ONE";
					}
					else{
						cardItem.Name = "CARD TWO";
					}

					GameObject m_card = Instantiate(m_regularDetailCard) as GameObject;
					m_card.transform.SetParent(m_detailCardContainer.transform);
					m_card.GetComponent<RectTransform>().SetDefaultScale();
					m_card.GetComponent<Button>().onClick.AddListener(() => {InitializeCardScreen(cardItem);});
                           }
                           count++;
			}

So what happens is that the parameter I passed in my InitializeCardScreen method will always be “CARD TWO” since it is the last object I instantiated and also since lambda only assigns the value of cardItem when the event onClick is triggered.

Is there any work around for this problem aside for creating ids for each instantiated item?

It’s a “feature” of Lambdas, makes no sense to me but I’m told it’s expected behavior, although I’m also told it should change in 5 but that’s just anecdotal as I don’t have 5.

You need to make a copy of anything you want to access for the lambda like this:

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

public class LambdaMenus : MonoBehaviour {
		
	public GameObject prefabButton;
	public RectTransform ParentPanel;
		
		
	// Use this for initialization
	void Start () {

		for(int i = 0; i < 5; i++)
		{
			GameObject goButton = (GameObject)Instantiate(prefabButton);
			goButton.transform.SetParent(ParentPanel, false);
			goButton.transform.localScale = new Vector3(1, 1, 1);

			Button tempButton = goButton.GetComponent<Button>();
			int tempInt = i;

			tempButton.GetComponentInChildren<Text>().text = "Button Numero " + i.ToString ();


			tempButton.onClick.AddListener(() => ButtonClicked(tempInt));
		}
	}


	//void SetButtonValues(Bu

		
	void ButtonClicked(int buttonNo)
	{
		Debug.Log ("Button clicked = " + buttonNo);
	}
		
}

You should be able to get the button number back on click so it can identify which button is which.