2017-05-15 2 views
0

Ich versuche, mein Einheitsprojekt zu bauen, aber ich kann nicht, da es ein Problem mit einer foreach-Schleife gibt. Genau darunter ist der Fehlercode, den ich erhalte, aber ich verstehe es nicht. Würde jemand erklären können, was eine mögliche Lösung sein könnte? Oder warum dieser Fehler auftritt?Spiel wird nicht wegen einer Foreach-Schleife in der Liste

InvalidOperationException: Sammlung wurde geändert; Aufzählungsoperation wird möglicherweise nicht ausgeführt. System.Collections.Generic.List`1 + Enumerator [UnityEngine.Vector3] .VerifyState() (unter /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs: 778)

System.Collections.Generic.List`1 + Enumerator [UnityEngine.Vector3] .MoveNext() (bei /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic /List.cs:784)

Player_Movement.Update() (bei Aktiva/Scripts/Spieler/Player_Movement.cs: 46)

Kontext zu geben, Code, den Sie eine Linie auf dem Bildschirm zeichnen zu sein und es erstellt eine Liste von Vektoren für den Spieler t o durchgehen.

void Update() 
{ 
    //when the player moves their finger accross the screen of the mouse button is held down 
    if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved) || (Input.GetMouseButton(0))) 
    { 
     //raycasthit variable called hit 
     RaycastHit hit; 
     //ray variable called ray 
     Ray ray; 
     //the ray variable is cast between the main camera and the mouse position 
     ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
     //if the physics racast hit then calulate the distance betwen the point (mouse position) and the camera 
     if (Physics.Raycast(ray, out hit)) 
     { 
      //save the positon as the nextPosition 
      nextPosition = hit.point; 
      //save the nextPositions point's yaxis 
      nextPosition.y = yAxis; 
      //if there are positions inside of the position list 
      if (positionList.Count != 0) 
      { 
       //then for each vector3 position in the list 
     Line 46 ===> foreach(Vector3 t in positionList) 
       { 
        //if there is no posiiton in the list where one should be 
        if (nextPosition != t) 
        { 
         //then create a position 
         positionList.Add(nextPosition); 
        } 
       } 
      } 
      else 
      { //otherwise create a position in the position list 
       positionList.Add(nextPosition); 
      } 
     } 
    } 
} 
+0

möglich dup: [so1] (http://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute) [so2] (http://stackoverflow.com/ questions/2024179/collection-was-modifiziert-enumeration-operation-may-not-execute-in-arraylist) –

+1

Kurz gesagt, Sie sollten keine Liste ändern (zB mit 'Add()') während Sie iterieren mit einer 'foreach' Schleife.Versuchen Sie, Ihre Logik neu zu strukturieren, so dass Sie dies nicht tun müssen. Außerdem ... bin ich mir nicht sicher, ob dein Code das tut, was du denkst. Zur Zeit wird 'nextPosition' zur Liste hinzugefügt für ** jedes ** Element in der Liste, das nicht mit' nextPosition' übereinstimmt, was nicht richtig erscheint. – Serlite

Antwort

1

Der Grund, dass Sie diese Ausnahme, wenn es darum, dass Sie versuchen, eine Sammlung zu ändern, während Sie über sie sind iterieren. Es gibt ein paar Möglichkeiten, wie Sie das umgehen können, aber wahrscheinlich ist der beste Weg, einfach Ihre Bedingung zu testen (enthält die Sammlung ein bestimmtes Element) und dann die Sammlung zu ändern (fügen Sie das Element hinzu), wenn der Test falsch ist.

Die Linq-Erweiterung Any kommt hier zum Einsatz. Sie gibt true zurück, wenn ein Element in der Sammlung der Bedingung entspricht. Einlochen ! vor es bedeutet, Sie suchen den Fall, dass es keine Objekte sind, die die Bedingung entsprechen:

if (!positionList.Any(position => position == nextPosition)) 
{ 
    positionList.Add(nextPosition); 
} 

Aber man kann dies auch ohne Linq tun, die Contains Methode verwendet, die eigentlich einfacher und wohl besser lesbar: auch

if (!positionList.Contains(nextPostition)) 
{ 
    positionList.Add(nextPostition); 
} 

Beachten Sie, dass diese Antworten auch einen Fehler im Code zu fixieren. Um den Fehler aufzudecken und immer noch den Fehler zu vermeiden, können Sie ToList() auf der Sammlung in der for Schleife aufrufen, etwa so:

foreach(Vector3 t in positionList.ToList()) 
{ 
    //if there is no posiiton in the list where one should be 
    if (nextPosition != t) 
    { 
     //then create a position 
     positionList.Add(nextPosition); 
    } 
} 

Der Aufruf von ToList() hier tatsächlich schafft eine neue Kopie der Liste und iteriert, dass man Es gibt also keinen Konflikt, wenn das Original geändert wird. Sie werden jedoch feststellen, dass Ihr vorhandener Code bei jedem Auftreten einer Nichtübereinstimmung nextPosition zur Liste hinzufügt, was meines Erachtens nicht Ihr beabsichtigtes Verhalten ist.

+0

Danke Rufus! Ich schaue in Listen und die Funktionalität in Einheit und es scheint keine List.Any Funktion zu sein. Würdest du zufällig wissen, wie ich darauf zugreifen kann? Gibt es eine Sammlung, auf die ich verweisen muss? oder ist es exklusiv für bestimmte Arten von Listen? –

+0

Ja, es ist eine Erweiterung von Linq. Sie benötigen diese Zeile am Anfang der Datei: 'using System.Linq;' –

+0

Erstaunlich! Rufus Ich könnte dich küssen: D –

1

Sie können keine Liste (dh .Add() darauf) ändern, während über sie iterieren.

Ihr Anpassungselement finden, dann fügen Sie wenn nötig:

if(positionList.FirstOrDefault(t => nextPosition == t) != null) 
    positionList.Add(nextPosition); 
+0

Vielen Dank für Ihre Antwort :) Also mit PositionList.FirstOrDefault scheint es mir nicht, dass Funktionalität mit Listen. Gibt es eine Sammlung, die ich mit Einheit verwenden sollte, oder funktioniert diese Funktionalität nur mit Listen vom Typ int? –

+0

Hey Mathias! Nochmals vielen Dank für Ihre Hilfe: D Ich schätze es sehr. Ich fand heraus, dass ich 'using System.Linq' verwenden sollte –

Verwandte Themen