Jump to content
Unity Insider Forum

"InvalidOperationExeption"


Singular

Recommended Posts

Hallo zusammen, ich habe hier einen Fehler, mit dem ich nichts anfangen kann. Ich bin auch schon auf die Suche gegangen und habe den Fehler in meinem Script gefunden... zumindest weiß ich was sein Problem ist aber ich weiß nicht warum.

Soviel vorne Weg: Ich möchte, dass der Spieler, wenn er an seiner Station andockt, die eingesammelten Mineralien in der Station abladen kann.

Achso, der Fehler den ich bekomme ist dieser hier:

image.png.e5d0895c6cfc9352143a52a812544211.png

Ich habe folgende Scripts von Scriptable Objects:

Ein SO für den Spieler (gekürzte Fassung für das, was mein Problem betrifft):

public class PlayerAttribiutes : ScriptableObject
{
    [Header("Frachtraum")]
    public List<MineralObject> cargo;
    public int cargoSpace;
    public bool cargoFull;
      
          private void CheckCargoSpace()
    {
        if (cargo.Count >= cargoSpace)
        {
            cargoFull = true;
        }
        else
        {
            cargoFull = false;
        }
    }
      
          public void RemoveMineralFromCargo(MineralObject mineral)
    {
        cargo.Remove(mineral);
    }
}

 

Ein SO für die Station:

 

public class StationDataBase : ScriptableObject
{
    public int mineralBlue;
    public int mineralRed;
    public int mineralGreen;
    public int mineralYellow;
    public int mineralWhite;

    private int cargoStation;
    private int cargoStationMax = 10;
    private bool cargoStationOnMax = false;

    public PlayerAttribiutes playerA;
    

    public void AddCargoToStation()
    {
        foreach(MineralObject mineral in playerA.cargo)
        {
            CheckCargoFull();

            if (cargoStationOnMax)
            {
                break;
            }
            else
            {
                switch (mineral.colorID)
                {
                    case 1:
                        mineralBlue++;
                        playerA.RemoveMineralFromCargo(mineral);  //Das hier ist übrigens das Problem
                        break;
                    case 2:
                        mineralRed++;
                        playerA.RemoveMineralFromCargo(mineral);  //Hier auch...
                        break;
                    case 3:
                        mineralGreen++;
                        playerA.RemoveMineralFromCargo(mineral);  // ...
                        break;
                    case 4:
                        mineralYellow++;
                        playerA.RemoveMineralFromCargo(mineral);  // ...
                        break;
                    case 5:
                        mineralWhite++;
                        playerA.RemoveMineralFromCargo(mineral);  // ...
                        break;
                }
            }
        }
    }

    private void CheckCargoFull()
    {
        cargoStation = 0;

        cargoStation += mineralBlue + mineralRed + mineralGreen + mineralYellow + mineralWhite;

        if (cargoStation >= cargoStationMax)
        {
            cargoStationOnMax = true;
        }
        else
        {
            cargoStationOnMax = false;
        }
    }
}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey Singular ...

Generell: Die gesamte Fehlermeldung mit stacktrace und Zeile in der der fehler auftritt hier rein zu kopieren wäre hilfreich. Allerdings ist bei diesem Fehler hier ziemlich offensichtlich was passiert...

du iterierst in der StationDataBase klasse über deine Player.Cargo liste und entfernst dann innerhalb der Schleife elemente aus der Liste. Das ist nicht erlaubt (InvalidOperation) da du ja damit die liste veränderst.

Damit das funktioniert müsstest du vor der schleife sowas in der art schreiben wie:

// erstmal eine neue liste erzeugen... 
List<MineralObject> copiedCargoList = new List<MineralObject>(playerA.cargo);
// und dann über die kopierte liste iterieren
foreach(MineralObject mineral in copiedCargoList)
{
  // hier kommt deine Schleife
}

Viele Grüße

Cxyda

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 20 Minuten schrieb Cxyda83:

Hey Singular ...

Generell: Die gesamte Fehlermeldung mit stacktrace und Zeile in der der fehler auftritt hier rein zu kopieren wäre hilfreich. Allerdings ist bei diesem Fehler hier ziemlich offensichtlich was passiert...

Ähhh... was? Zeile usw steht da nicht. Das ist tatsächlich nur das was ich kopiert habe. Mehr von der Fehlermeldung habe ich nicht. Was ist ein stacktrace? Mache ich in Zukunft gerne, keine Frage. Dann muss ich wahrscheinlich auch nicht ewig suchen wo mein Fehler liegt...

Zitat

du iterierst in der StationDataBase klasse über deine Player.Cargo liste und entfernst dann innerhalb der Schleife elemente aus der Liste. Das ist nicht erlaubt (InvalidOperation) da du ja damit die liste veränderst.

Damit das funktioniert müsstest du vor der schleife sowas in der art schreiben wie:


// erstmal eine neue liste erzeugen... 
List<MineralObject> copiedCargoList = new List<MineralObject>(playerA.cargo);
// und dann über die kopierte liste iterieren
foreach(MineralObject mineral in copiedCargoList)
{
  // hier kommt deine Schleife
}

Viele Grüße

Cxyda

Aber das war der Fehler. Perfekt. Ich danke dir!

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 14 Stunden schrieb Singular:

Zeile usw steht da nicht. Das ist tatsächlich nur das was ich kopiert habe. Mehr von der Fehlermeldung habe ich nicht. Was ist ein stacktrace? Mache ich in Zukunft gerne, keine Frage. Dann muss ich wahrscheinlich auch nicht ewig suchen wo mein Fehler liegt...

Der Fehler wird ja an zwei Stellen angezeigt. Wenn's die allerletzte Meldung ist, dann unten links in der Fußzeile des Editors, aber auf jeden Fall in der Liste der Meldungen in der Konsole. Diese solltest du immer offen haben. Die hat eine Ober- und eine Unterhälfte. In der oberen hast du die Liste aller Meldungen - Fehler, Warnungen und Infos - und wenn du in dieser Liste eine Meldung anklickst, dann siehst du in der unteren Hälfte den Stacktrace.

Der Stacktrace ist der Pfad, den das Programm durch den Code genommen hat, um zu der Meldung zu kommen. So etwas wie:

  • Unity ruft Update() auf
  • In Update(), Zeile X, wird Methode Blubb() aufgerufen
  • In Blubb(), Zeile Y, ist eine Exception aufgetreten

So kannst du quasi den "Tathergang" nachvollziehen, der zur Meldung geführt hat. Und im Stacktrace stehen dann eben auch, wie man sieht, die Zeilennummern.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich müsste den Fehler nochmal rekonstruieren, aber ich meine, dass ich keine zweite Zeile bei diesem Fehler hatte. Deswegen habe ich den Stacktrace selber nachverfolgen müssen. Oder gibt es eine möglichkeit ohne gleich in jeder Zeile und in jeder Methode Debug.Log(""); aufzurufen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Singular:

Oder gibt es eine möglichkeit ohne gleich in jeder Zeile und in jeder Methode Debug.Log(""); aufzurufen?

Ne, aber besser. Je nach dem, welche IDE du benutzt, sieht das vorgehen ein bisschen anders aus, aber du willst den Debugger benutzen. Mit dem kannst du sogenannte "Haltepunkte" (Break Points) an Zeilen setzen und wenn das Programm an einer Zeile mit Haltepunkt vorbeikommt, wird das Programm angehalten und du kannst per Hand Zeile für Zeile weitergehen. Schau dir mal an, wie das bei deiner IDE funktioniert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...