2014-09-13 60 views
0

在Unity 4.6中嘗試新的uGUI,編寫按鈕腳本...遍歷一個目錄併爲每個文件創建一個按鈕... AddListener位中f.Name的值應該爲每個按鈕獨立設置。相反,每個按鈕都具有要處理的最後一個f.Name的值(目錄中按字母順序排列的最後一個文件)。有任何想法嗎?Unity 4.6,如何阻止共享偵聽器的克隆?

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

普萊斯使用unity3d這樣的問題。 – 2014-09-13 03:21:14

回答

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); 
} 

是(或多或少)等效於:該v聲明出for循環的範圍,然後僅重新分配在每個通

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的引用。因此,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)); 
} 
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)); 
} 

:)

相關問題