How to pass arguments to callback functions using IPointerClickHandler

Since I don’t want to use the Unity genuine Button component, I’m using an alternative class for Button that I created with reference to someone else’s source.

public class CustomButton:Monobehaiviour,IPointerClickHandler{
    public System.Action onClickCallback;
    public void OnPointerClick(PointerEventData eventData)
    {
        onClickCallback?.Invoke();
    }
}

However, I noticed a problem when using it in combination with List.

private int BUTTON_NUM = 3;
void Start()
{
    for (int i = 0; i < BUTTON_NUM; i++)
    {
        roomButtons[i].onClickCallback = () => {
            OnClickRoomBtn(i);
        };
    }
}

private void OnClickRoomBtn(int roomNo)
{
    Debug.Log("RoomNo: "+ roomNo);
}

Click roomButtons[0] to

RoomNo: 3

As mentioned above, I noticed that I can’t pass the arguments as intended in the For syntax.

void Start()
{  
    roomButtons[0].onClickCallback = () => {
        OnClickRoomBtn(0);
    };
    roomButtons[1].onClickCallback = () => {
        OnClickRoomBtn(1);
    };
    roomButtons[2].onClickCallback = () => {
        OnClickRoomBtn(2);
    };
}

Click roomButtons[0] to

RoomNo: 0

In this way, if you write only the number of buttons, it will work, but I want to use the For statement.
Please let me know how I can modify this format to make it more convenient.

Simply put, you’d have to introduce your own delegate with parameters. Such as System.Action<int>.

1 Like
    for (int i = 0; i < BUTTON_NUM; i++)
    {
        roomButtons[i].onClickCallback = () => {
            OnClickRoomBtn(i);
        };
    }

That will capture reference to i not the value of i. So all the callbacks you create refer to the same i variable. This may be slightly surprising since in rest of C# it’s almost impossible to make a reference to value type variables, and parts that allow you to make something similar require to be somewhat explicit about it.

So you need to do it this way:

    for (int i = 0; i < BUTTON_NUM; i++)
    {
        int buttonNum = i;
        roomButtons[i].onClickCallback = () => {
            OnClickRoomBtn(buttonNum);
        };
    }
3 Likes

I just realized that I don’t understand delegates very well. I will take this opportunity to study. Thank you very much.

Thank you, I was surprised how easy it was to solve.
It was necessary to repeat, including the definition of variables.