Assigning UI Button Listeners in for loop results in incorrect pass.
I am creating buttons and assigning their listeners at runtime, but the code below, for some unknown reason, causes every button to be passed the value from the last item in the list 'Abilities'.
So in the bottom function, despite a different value in each loop, the same value is passed to the button listener.
void CreateButtons ()
{
for(int i = 0; i < abilities.Count; i++)
{
Ability a = abilities[i];
string aName = a.name;
GameObject go = (GameObject)Instantiate(abilityButton,Vector3.zero, Quaternion.identity);
go.transform.SetParent(buttonLayout.transform);
go.GetComponent<RectTransform>().localScale = Vector3.one;
go.GetComponent<Button>().onClick.RemoveAllListeners();
abilityButtons.Add(go);
go.GetComponent<Image>().sprite = Resources.Load<Sprite>("Art/UI/Buttons/" + a.name);
AddButtonListener(aName, go);
}
}
void AddButtonListener(string _name, GameObject buttonGO)
{
Debug.Log(_name); // <------ This logs correctly a different value on every loop.
//Where as this gives every button the same name argument, equal to the last in the list.
buttonGO.GetComponent<Button>().onClick.AddListener(() => UseAbility(_name));
}
Answer by lassade · Jan 24, 2016 at 01:36 PM
Create a variable inside to AddButtonListener and simple assing it with _name then pass it to the callback, this way the variable should be captured (search for this term for more info on the subject).
void AddButtonListener(string _name, GameObject buttonGO) {
string localName = _name;
buttonGO.GetComponent<Button>().onClick.AddListener(() => UseAbility(localName));
}
Adding callbacks for buttons in a Coroutine also have its own pitfalls so beware.
Check this answer post http://stackoverflow.com/questions/271440/captured-variable-in-a-loop-in-c-sharp
I'm afraid that doesn't work. I understand that you need to store each different version of the string in memory, but for some reason even this doesn't solve it.
Your answer
Follow this Question
Related Questions
anonymous function does not take `0' arguments 0 Answers
Assigning different buttons click events to the same function with a parameter dynamically 1 Answer
Load Scene Replay Problem 1 Answer
Problem using two unity ad listener scripts in my project, is this possible? 0 Answers
Add listener on Objects that are part of dictionary 1 Answer