在Unity 4.6中尝试新的uGUI,编写按钮脚本...遍历目录并为每个文件创建一个按钮... AddListener位中的f.Name值应该为每个按钮独立设置。相反,每个按钮都具有要处理的最后一个f.Name的值(目录中按字母顺序排列的最后一个文件)。有什么想法吗?
foreach (FileInfo f in fileInfo) {
Button btnCurrLvl = (Button) Instantiate(btnLvl);
btnCurrLvl.GetComponentInChildren<Text>().text = f.Name.Remove(f.Name.Length-5);
Debug.Log(f.Name); // f.Name is different every time
btnCurrLvl.name = f.Name; // renaming the btns works
btnCurrLvl.GetComponent<Button>().onClick.AddListener(() => LoadLocalLvl(f.Name)); // all the listeners on all created buttons are set to the last value of f.Name!?
}
答案 0 :(得分:1)
在foreach循环中使用lambda表达式时要小心。以下代码:
var someList = new List<int> {1, 2, 3, 4};
var listOfClosures = new List<Func<int>>();
foreach (int v in someList)
{
listOfClosures.Add( () => v );
}
(或多或少)等同于:
var someList = new List<int> {1, 2, 3, 4};
var listOfClosures = new List<Func<int>>();
int v;
for (int i = 0; i < someList.Count; i++)
{
v = someList[i];
listOfClosures.Add( () => v );
}
请注意,v声明在for循环的范围之外,然后仅在每次传递时重新分配。另请注意,闭包只保留对变量v的引用。因此,listOfClosures中的每个闭包在调用时都会返回4(最后一个值v被赋值)。
在你的情况下也是如此:
foreach (FileInfo f in fileInfo) {
btnCurrLvl.GetComponent<Button>().onClick.AddListener(() => LoadLocalLvl(f.Name));
}
所有的闭包都会引用相同的f。 尝试在每个循环传递上创建新变量:
foreach (FileInfo f in fileInfo) {
var name = f.Name;
btnCurrLvl.GetComponent<Button>().onClick.AddListener(() => LoadLocalLvl(name));
}
答案 1 :(得分:0)
string captured;
foreach (FileInfo f in fileInfo) {
Button btnCurrLvl = (Button) Instantiate(btnLvl);
btnCurrLvl.GetComponentInChildren<Text>().text = f.Name.Remove(f.Name.Length-5);
btnCurrLvl.name = f.Name;
captured = f.Name;
btnCurrLvl.GetComponent<Button>().onClick.AddListener(() => LoadLocalLvl(captured));
}
:)