添加带有委托的按钮侦听器以停止更新方法参数

Add Button listener with delegate to stop updating method argument

假设我在 Unity 中有一个 canvas,我想在其中创建 5 个按钮。每次按下按钮时,它都会显示 This is button n.i,其中 i 从 0 变为 4。这是我目前使用的代码:

public Button buttonPrefab; //set from inspector
void SetButtons()
{
    Button newObj;
    for (int i = 0; i < 5; i++)
    { //loop 5 times, creates a button using buttonPrefab and assign ButtonNumber() method to it
        newObj = Instantiate(buttonPrefab, transform);
        newObj.onClick.AddListener(delegate { ButtonNumber(i); });
    }
}
void ButtonNumber(int nButton)
{
    Debug.Log($"This is button n.{nButton}");
}

我使用 onClick.AddListener 为按钮分配一个方法,并且由于该方法需要参数,我一直使用 delegate.

传递它们

问题是,对于我按下的每个按钮,结果总是 This is button n.5

所有按钮似乎总是根据 i 的最新值进行更新,即使我希望方法在分配时保存 i 值。

我可以使用这个脚本使脚本工作:

public Button buttonPrefab; //set from inspector
void SetButtons()
{
    Button newObj;
    for (int i = 0; i < 5; i++)
    {
        newObj = Instantiate(buttonPrefab, transform);
        switch (i)
        {
            case 0:
                newObj.onClick.AddListener(delegate { ButtonNumber(0); });
                break;
            case 1:
                newObj.onClick.AddListener(delegate { ButtonNumber(1); });
                break;
            case 2:
                newObj.onClick.AddListener(delegate { ButtonNumber(2); });
                break;
            case 3:
                newObj.onClick.AddListener(delegate { ButtonNumber(3); });
                break;
            case 4:
                newObj.onClick.AddListener(delegate { ButtonNumber(4); });
                break;
        }
    }
}
void ButtonNumber(int nButton)
{
    Debug.Log($"This is buton n.{nButton}");
}

但我不会称之为“智能”解决方案。

我可以做些什么来让按钮在第一个脚本中起作用吗?

只需更改为:

  var x = i;
  newObj.onClick.AddListener(delegate { ButtonNumber(x); });

瞧。

发生的事情称为 i 变量的“捕获”,您可以在上面找到大量的问题和答案,例如: Captured variable in a loop in C#