0

I am adding a list of buttons in code for which I would like to add a click listener.

I am able to add the listener, the issue is I would like to know the button that called the listener.

I have tried the following method, but the passed value to the listener is always the same:

foreach (...)
{
    var button = (Button)GameObject.Instantiate(...);

    packIndex++;

    button.onClick.AddListener(() => this.OnButtonClick(packIndex));
}

public void OnButtonClick(int idx)
{
    // idx is always the latest value in the above loop
}

TL;DR

How do you find the caller from a button click listener?

rhughes
  • 9,257
  • 11
  • 59
  • 87

2 Answers2

1

Try this

var button = (Button)GameObject.Instantiate(...);
packIndex++;
button.name = "Button" + packIndex;
button.onClick.AddListener(() => this.OnButtonClick(button));

public void OnButtonClick(Button button)
{
// idx is always the latest value in the above loop
}
Nain
  • 1,204
  • 1
  • 12
  • 17
1

You almost have it. To store the index, you need to "capture" the packIndex variable by making a copy of packIndex inside the for loop. You can see a good explanation of this "closure in a for loop" phenomenon here.

The following code should work:

foreach (...)
{
    var button = (Button)GameObject.Instantiate(...);

    packIndex++;
    var packIndexCopy = packIndex;

    button.onClick.AddListener(() => this.OnButtonClick(packIndexCopy));
}

public void OnButtonClick(int idx)
{
    // idx is always the latest value in the above loop
}

Note that the answer by @Nain will also work because in that case the "button" object in AddListener(() => this.OnButtonClick(button)); refers to a new object that's created each time in the foreach loop, so the compiler will correctly bind the OnButtonClick handler to that 'new' copy. In fact, passing the Button object in directly feels a little bit cleaner, but that depends on the rest of your code.

If you are unfamiliar with closures (which are really confusing and take a long time to understand!), this article has a good explanation.

P.S. I wrote a small Component to test this, here's the gist for it in case it helps.

Community
  • 1
  • 1
Julia Schwarz
  • 2,610
  • 1
  • 19
  • 25