2017-04-10 1 views
1

Ich habe einige Schaltflächen, die jeweils eine Ebene darstellt und möchten den Listener programmgesteuert hinzufügen, aber nicht ganz vertraut mit der Lambda-Funktion von C# (vielleicht etwas Verschluss Sache?), Es ist, was ich jetzt mache :Einheit hinzufügen Schaltfläche mit Skript programmgesteuert mit Parameter

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

aber die Linie:

ApplicationModel.currentLevel = levels[i]; 

levels ist ein List<Level> und ApplicationModel ist eine Klasse, die Informationen hält nach this post aber es hält eine ArgumentOutOfRang geben 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) 

Antwort

2

es eine ArgumentOutOfRangeException hält geben:

das Problem, das Sie haben sind, ist, dass die Variable i durch die Zeit, die für die Schleife abgeschlossen verwendet wird und der Wert von i ist levels.Count.

dies wird als erfasst Variablen bezeichnet:

  • Der Wert einer Variablen zu der Zeit ist es nicht zu der Zeit verwendet wird, erfasst wird.
  • Die Lebensdauer einer erfassten Variablen wird verlängert, bis alle Verschlüsse , die auf die Variable verweisen, für die Garbage Collection infrage kommen.

Rather, was Sie tun können, ist ein bisschen eine Köder Variable erstellen wir es capturedIndex anrufen und die Lambda-Ausdruck der capturedIndex statt der Indexer der for-Schleife zu erfassen.

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

Literatur:

+1

Danke, es hilft. Es wird noch größer, wenn Sie weitere Referenz hinzufügen können, um weiterzulesen: D – armnotstrong

+0

@armnotstrong, wenn es geholfen hat, würde ich es schätzen, wenn Sie die Antwort als akzeptiert markieren und sicher, dass ich einige Links für Referenzen anhängen werde. –

+1

danke @Ousmane, ich werde hinein graben: D – armnotstrong

Verwandte Themen