Błąd przy usuwaniu obiektu z listy

Programowanie w Unity.

Błąd przy usuwaniu obiektu z listy

Postprzez avengerarrow » 23 Lis 2018, 07:24

Collection was modified; enumeration operation may not execu;
Dostaję taki błąd kiedy w metodzie RemoveUnit dodaję tę linijkę teams[unit.tag].Remove(unit);
Jak to naprawić?
Kod: Zaznacz wszystko
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurnManager : MonoBehaviour
{
    static Dictionary<string, List<UnitMovement>> teams = new Dictionary<string, List<UnitMovement>>();
    static Queue<string> teamTag = new Queue<string>();
    static Queue<UnitMovement> turnOfTheTeam = new Queue<UnitMovement>();

    private bool firstTurn = true;
    public static string currentTeam;

    void Update()
    {
        if (turnOfTheTeam.Count == 0) //Jezeli kolejka pusta uruchom Inicjalizacje
        {
            if (firstTurn)
            {
                FirstTurnPlayer();
                firstTurn = false;
            }
            InitializationTeamTurnQueue();
        }
    }

    static void InitializationTeamTurnQueue()
    {
        List<UnitMovement> teamList = teams[teamTag.Peek()];

        currentTeam = teamTag.Peek();

        foreach (UnitMovement unit in teamList)
        {
            turnOfTheTeam.Enqueue(unit);
        }

        StartTurn();
    }

    public static void StartTurn()
    {
        if (turnOfTheTeam.Count > 0)
        {
            turnOfTheTeam.Peek().BeginUnitTurn();
        }
    }

    public static void EndTurn()
    {
        UnitMovement unitMovement = turnOfTheTeam.Dequeue();
        unitMovement.EndUnitTurn();

        if (turnOfTheTeam.Count > 0)
        {
            StartTurn();
        }
        else
        {
            string team = teamTag.Dequeue();
            teamTag.Enqueue(team);
            InitializationTeamTurnQueue();
        }
    }

    public static void AddUnit(UnitMovement unitMovement)
    {
        List<UnitMovement> list;
        if (!teams.ContainsKey(unitMovement.tag))
        {
            list = new List<UnitMovement>();
            teams[unitMovement.tag] = list;

            if (!teamTag.Contains(unitMovement.tag))
            {
                teamTag.Enqueue(unitMovement.tag);
            }
        }
        else
        {
            list = teams[unitMovement.tag];
        }

        list.Add(unitMovement);
    }

    public static void RemoveUnit(UnitMovement unit) //TEST
    {
        foreach (UnitMovement unitMovement in teams[unit.tag])
        {
            if (unitMovement.GetComponent<BaseStats>().HP <= 0)
            {
                //teams[unit.tag].Remove(unit);
                Debug.Log("USUNIETY :)");
            }
        }
    }

    void FirstTurnPlayer()
    {
        if ((teamTag.Peek() != "Player"))
        {
            string team = teamTag.Dequeue();
            teamTag.Enqueue(team);
        }
    }
}
avengerarrow
 
Posty: 5
Rejestracja: 21 Lis 2018, 21:10
Has thanked: 0 time
Been thanked: 0 time

Re: Błąd przy usuwaniu obiektu z listy

Postprzez dawid621 » 23 Lis 2018, 07:32

Użyj pętli for zamiast foreach.
dawid621
 
Posty: 186
Rejestracja: 07 Sie 2016, 18:52
Has thanked: 0 time
Been thanked: 0 time

Re: Błąd przy usuwaniu obiektu z listy

Postprzez Hostur » 23 Lis 2018, 08:48

Nie możesz modyfikować kolekcji w trakcie iteracji przez nią
Możesz to obejść usuwając element za pomocą linq albo w pętli for jak pisze Dawid ale wtedy musisz pamiętać o deikrementacji zmiennej indexu
Kod: Zaznacz wszystko
for(int i = 0; i < Length; i++)
{
  if(remove) --i;
}


Pomyśl też jak sobie cachować BaseStats żeby nie wołać GetComponent<BaseStats> w tej pętli.
Możesz zawołać to w samym UnitMovement i wystawić publiczny geter
Hostur
 
Posty: 696
Rejestracja: 05 Sie 2015, 07:36
Has thanked: 0 time
Been thanked: 0 time

Re: Błąd przy usuwaniu obiektu z listy

Postprzez avengerarrow » 23 Lis 2018, 09:33

@Hostur Czyli mogę w funkcji tworzyć nową listę i tam przechodząc w pętli foreach wrzucam obiekty które potrzebuje. A na końcu przypisuje do listy przez którą przechodziłem listę którą stworzyłem?
avengerarrow
 
Posty: 5
Rejestracja: 21 Lis 2018, 21:10
Has thanked: 0 time
Been thanked: 0 time

Re: Błąd przy usuwaniu obiektu z listy

Postprzez Hostur » 23 Lis 2018, 20:43

Jak chcesz to zrobić porządnie to zastanów się jak tego NIE usuwać tylko np ustawiać jako nieaktywne dodając jakąś flagę.
Jeśli się nie da to radziłbym Ci tam ustawiać nulla zamiast wołać remove.
Remove powoduje skopiowanie wszystkich elementów tablicy na prawo od usuwanego elementu o jeden index w lewo.
To jest kosztowna operacja.
Hostur
 
Posty: 696
Rejestracja: 05 Sie 2015, 07:36
Has thanked: 0 time
Been thanked: 0 time


Wróć do Skrypty

Kto jest na forum

Użytkownicy przeglądający to forum: Brak zarejestrowanych użytkowników oraz 2 gości

cron