- Home /
When using AddListener, can multiple buttons be registered to the same function?
As the title suggests, is it possible to have n number of buttons register to the same function? I have this so far:
foreach (LevelInfo info in m_LevelList)
{
info.m_LevelButton.onClick.AddListener( () =>
{
Function(info.m_LevelButton);
} );
}
void MyFunction(Button button)
{
Debug.Log(button.name);
}
When I use this in application, it only prints the name of the last button in the list.
So, is it possible to register multiple buttons to the same function?
Thanks!
Answer by Bunny83 · Jun 01, 2016 at 03:58 AM
You are closing over the foreach variable with your anonymous method. Each closure will reference the same variable. I'm not going to explain it again, just read the questions at the end which all have the same problem.
The solution is simple. Just create a local variable inside the for loop. This variable will be a new variable each iteration.
foreach (LevelInfo info in m_LevelList)
{
// local variable which the closure will close over.
Button button = info.m_LevelButton;
info.m_LevelButton.onClick.AddListener( () =>
{
Function(button);
} );
}
Some related questions about the same topic:
http://answers.unity3d.com/questions/1159366/add-an-iteration-of-onclick-methods.html http://answers.unity3d.com/questions/1014842/weird-for-loop-counter-issue-with-threading.html http://stackoverflow.com/questions/227820/why-is-it-bad-to-use-an-iteration-variable-in-a-lambda-expression https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/
Thanks a bunch! I wish I found those links earlier, would have saved me some time. Guess I need to work on my Google-fu :)
Does the same thing apply when that foreach loop is inside a coroutine?
Because I know about this problem and do the local variable trick, but recently I happen to encounter the same situation in a coroutine, where the trick didn't work. As this answer pointed out, I moved the loop body into another function and it did the fix. (Edit: Converting foreach to for didn't)
$$anonymous$$y guess is that it's some clash between references created by the coroutine's on the fly anonymous type and the anonymous function's underlying mechanism. (I might be horribly wrong here. Please correct me if I'm mistaken.)