C#/Unity: How can I determine which prefab button was pressed?

When my program starts, I read a list of players and create a prefab for each that has some buttons in it. When I click on the appropriate button (button[0]), I need my code to call my SelectPlayer() function and determine which player was clicked on so they can be highlighted and loaded into the active players in my game. Here’s my code:

for (int i = 0; i < numberOfPlayers; i++) // Disk players read, now display their stats for selection
{
newObj = (GameObject)Instantiate(prefabPlayerPanel, objContent.transform);
var buttons = newObj.GetComponentsInChildren();
buttons[0].onClick.AddListener(() => SelectPlayer(i));
}

However, this appears to pass to SelectPlayer the current (final) value of i (which is numberOfPlayers), not the value of i when that object was instantiated, i.e., the newObj instance associated with that player.

I need SelectPlayer() to know for which newObj instance the button was pressed. Thanks!

1 Like

Hi @Burlisoft , the behavior you are seeing is because the lambda expression is capturing the variable, not the value of it. In the “for loop” the value of the variable is not unique on each iteration, but the same variable is used for the duration of the loop and as a result, you’ve captured the same value of the variable.

You can solve this by using a temporal variable:

for (int i = 0; i < numberOfPlayers; i++) // Disk players read, now display their stats for selection
{
newObj = (GameObject)Instantiate(prefabPlayerPanel, objContent.transform);
var buttons = newObj.GetComponentsInChildren();
var temp = i;
buttons[0].onClick.AddListener(() => SelectPlayer(temp));
}

If you want to learn more about this behavior, take a look at these blogs:

1 Like

I was close! Thanks so much; that did it. Great to get such a clear answer! On a related note, is there a way to add a variable to the prefab, to which I can assign a value (in this case, the value of temp)? That way, I can reference that object’s location in the file anytime I need it.