I’m dynamically generating UI buttons based on locations the player knows about.
How do I add my function to the OnClick listener?
foreach (string a in places)
{
GameObject go = (GameObject)Instantiate(buttons);
go.transform.parent = panel.transform;
go.transform.localScale = new Vector3(1, 1, 1);
Button b = go.GetComponent<Button>();
b.onClick.AddListener(...???...)
}
As a work around I made a “PointerDown” trigger on the button object but I would rather do it properly and use Unity’s onclick handling.
I’m just going to make some assumptions here; Since you said in the other post about this, that you tried my version with lambda expressions and that you always got the last button being called, my guess it that you are trying to somehow use the string from the loop in the listener. The issue you are having there is with capturing the loop iterator instead of the value.
Eg. if you are going to write it something like this:
foreach (string a in places)
{
GameObject go = (GameObject)Instantiate(buttons);
go.transform.parent = panel.transform;
go.transform.localScale = new Vector3(1, 1, 1);
Button b = go.GetComponent<Button>();
b.onClick.AddListener(() => MyMethod(a));
}
At the time where you click the button MyMethod is going to receive the element from places that was last used in the loop (if you executed the full loop, then this will always be the last one)
You can solve this by capturing the variable separately before adding the listener.
foreach (string a in places)
{
GameObject go = (GameObject)Instantiate(buttons);
go.transform.parent = panel.transform;
go.transform.localScale = new Vector3(1, 1, 1);
Button b = go.GetComponent<Button>();
string captured = a;
b.onClick.AddListener(() => MyMethod(captured));
}
or alternatively by making the part with listener adding a separate method:
foreach (string a in places)
{
GameObject go = (GameObject)Instantiate(buttons);
go.transform.parent = panel.transform;
go.transform.localScale = new Vector3(1, 1, 1);
Button b = go.GetComponent<Button>();
AddListener(b, a); // Using the iterator as argument will capture the variable
}
// Outside of method running the above
void AddListener(Button b, string value)
{
b.onClick.AddListener(() => MyMethod(value));
}