Hi, I just have a quick question about buttons as I seam to be having some trouble.
I have an array of buttons that get created in a loop. And then for each button there is a listener,
Like so:
for (int yy = 0; yy < rows; yy++)
{
for (int xx = 0; xx < collumns; xx++)
{
//Location
Vector2 loc = new Vector2 (gameObject.GetComponent<RectTransform>().rect.position.x + slotSpace * xx,
gameObject.GetComponent<RectTransform>().rect.position.y - slotSpace * yy);
//Creates object in specific location and sets it as a child of another object.
invSlot[invIndex] = Instantiate (invButton, loc, Quaternion.identity);
invSlot[invIndex].transform.SetParent (this.gameObject.transform, false);
//Listener
invSlot[invIndex].GetComponent<Button> ().onClick.AddListener (ClickInvButton);
invIndex++;
}
}
I have this that runs when any of the buttons are clicked:
public void ClickInvButton()
{
Debug.Log ("Button pressed");
}
This runs fine however I need to figure out how to get the index of the button that was pressed.
I’d rather not have a script attached to each of the buttons that sets an int when in gets Instantiated.
Is there a way of doing this?
Thanks!
I think the best way to do this would be to replace your function/delegate parameter there with a lambda/inline function, which in turn calls your real function. e.g.:
invSlot[invIndex].GetComponent<Button> ().onClick.AddListener (() => {ClickInvButton(invIndex);});
...
public void ClickInvButton(int button) {
Further reading
1 Like
Hi, Thanks for getting back to me. I’ve had a play but the returned value is always 20 when I click a button.
invSlot[invIndex].GetComponent<Button> ().onClick.AddListener (() => ClickInvButton(invIndex));
or
invSlot[invIndex].GetComponent<Button> ().onClick.AddListener (() => {ClickInvButton(invIndex);});
public void ClickInvButton(int button)
{
Debug.Log (button);
}
The debug.log just returns 20 which is the size of the array.
I’m going to keep trying and check look more through the further reading. But if I am doing something painfully obvious then please do let me know! 
Thanks
I suspect many, many people have been in your shoes ( I have )
Oh, btw, promise if you read a little ways in you’ll find an explanation & a resolution
Ok so I’ve had a read through what you’ve linked and I’ve come up with this:
int buttonIndex = invIndex;
invSlot[invIndex].GetComponent<Button> ().onClick.AddListener (() => ClickInvButton(buttonIndex));
This works but I don’t really understand why.
I understand why it was returning 20 with every button before. It’s because invIndex was only that integer at the time it was created. By the end of the loop invIndex was at 20 and stayed at 20 because it hadn’t been told otherwise.
By setting a new int named buttonIndex it somehow remembers the int even though it’s changing through out the loop.
My head might explode.
Well, yes - the first part you got exactly right. The second part is that you’re making a new variable inside the loop (small inner scope), the next iteration a new variable is created, not the previous one changed. 
Glad it’s working for ya.
I have a much better understanding of it now, Thanks for that!
But I’ve come across a small hitch in my plan. What I would really like to do rather than detect a click i’d like to detect when the mouse is down, and then eventually detect when the mouse is up. So I think regardless of what how I want to implement these buttons I’ll have to use the event system on the button object. and then use a separate script which then talks to the parent object.
Unless there’s a way of me using something like the following:
invSlot[invIndex].GetComponent<Button> ().OnMouseDown.AddListener (() => ClickInvButton(buttonIndex));
I’ve done a bit of digging and reading about the place and as far as I can tell there’s not really any way of doing this. A simple one liner way that is anyway.
Unless any ones got any other ideas?
Thanks again
Did ya get that worked out?