2017-04-10 41 views
1

我有一些按鈕,每個代表一些級別,並希望以編程方式添加偵聽器,但不太熟悉C#的lambda函數(可能是一些封閉的東西?),這就是我現在做的:統一添加按鈕使用腳本編程方式與參數

for(int i=0; i<levels.Count; i++){ 
    //omit the making a button snippet 
    button.GetComponent<Button>().onClick.AddListener(() => 
    { 
     Debug.Log("load Scene"); 
     ApplicationModel.currentLevel = levels[i]; 

     SceneManager.LoadScene("Game"); 
     //Application.LoadLevel("Game"); 
    }); 
} 

但行:

ApplicationModel.currentLevel = levels[i]; 

levelsList<Level>ApplicationModel是一類根據this post 持有信息,但它一直給予ArgumentOutOfRang eException:

ArgumentOutOfRangeException: Argument is out of range. 
Parameter name: index 
System.Collections.Generic.List`1[Level].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) 
GameLevelManger+<initScrollPanel>c__AnonStorey0.<>m__0() (at Assets/GameLevelManger.cs:72) 

回答

2

它不斷給一個ArgumentOutOfRangeException:

您遇到的問題是,由當時的變量i使用for循環已完成和ilevels.Count

此稱爲捕獲的變量:

  • 一個變量的值是在它不是在它被捕獲時所使用的時間。
  • 捕獲的變量的生命週期會延長,直到引用該變量的所有關閉 纔有資格進行垃圾回收。

而你所能做的就是那種創建一個誘餌變量我們稱之爲capturedIndex,讓lambda表達式捕獲capturedIndex而非for循環的索引。

for(int i=0; i<levels.Count; i++){ 
    //omit the making a button snippet 
    int capturedIndex = i; // <-- let the lambda capture this rather than the indexer. 
    button.GetComponent<Button>().onClick.AddListener(() => 
    { 
      Debug.Log("load Scene"); 
      ApplicationModel.currentLevel = levels[capturedIndex]; 
      SceneManager.LoadScene("Game"); 
      //Application.LoadLevel("Game"); 
    }); 
} 

進一步閱讀:

+1

謝謝,它有幫助。如果你可以添加更多的 參考文獻,那麼它會更好:D – armnotstrong

+0

@armnotstrong如果它幫助我很感激它,如果你將答案標記爲已接受,並確定我會追加一些參考鏈接。 –

+1

感謝@Ousmane,我會深入研究它:D – armnotstrong

相關問題