首页 > 解决方案 > 添加带有委托的按钮侦听器以停止更新方法参数

问题描述

假设我在 Unity 中有一个画布,我想在其中创建 5 个按钮。每次我按下按钮时,它都会显示This is button n.ii从 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}");
}

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

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

标签: c#unity3dbuttondelegates

解决方案


只需更改为:

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

瞧。

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


推荐阅读