假设我在Unity中有一个画布,我想在其中创建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}");
}
但是我不会将其称为“智能”解决方案。
我可以做些什么使按钮在第一个脚本中起作用吗?
答案 0 :(得分:1)
只需更改为:
var x = i;
newObj.onClick.AddListener(delegate { ButtonNumber(x); });
Voila。
发生的事情称为i变量的“捕获”,您可以在其中找到大量的问题和答案,例如: Captured variable in a loop in C#