Removing items from list creates error

I’m trying to remove items from a list of GameObjects, but whenever I try to it gives an error during the game, and doesn’t remove the item. The error message it gives is: InvalidOperationException: Collection was modified; enumeration operation may not execute. I’m not sure if it’s just a simple mistake because this is my first game coded in Unity, but I can’t figure out whats going on. The code is below (I excluded the unimportant stuff):

...
private List<GameObject> enemies = new List<GameObject>();
...
GameObject newEnemy = Instantiate(Enemy, new Vector3(spawnPos, 6, -1), Quaternion.Euler(0, 0, Random.Range(0, 100)));
enemies.Add(newEnemy);
...
foreach (GameObject enemy in enemies){
            enemy.transform.rotation = Quaternion.Euler(0, 0, EnemyRot);
            EnemyRot += spinSpeed;
            if (enemy.transform.position.y < -5){
                enemies.RemoveAt(0);
            }
        }

Thanks!

When removing items from a collection, you can either enumerate said collection backwards, or, build a list of items to remove as you run through the initial collection, then afterwards, run through the temporary list of items to remove, removing each one from the main list.

In code form:

int count = someList.Count;
for (int i = count - 1; i >= 0; i--)
{
    var item = someList[i];
    if (item // passes some condition)
    {
        someList.RemoveAt(i);
    }
}

// OR

var toRemove = new List<SomeType>();

foreach (var item in someList)
{
    if (item // passes some condition)
    {
        toRemove.Add(item);
    }
}

foreach (var item in toRemove)
{
    someList.Remove(item);
}
1 Like

This is a .NET thing in general, not specific to Unity. Making changes to a collection during iteration via an enumerator (happens when using foreach) leads to undefined behavior, so you generally want to avoid using enumerators in these cases.

If the order doesn’t matter, you can use something like this to reduce how much you end up moving elements around while removing elements.

    public void RemoveAtSwapBack<T>(IList<T> list, int index)
    {
        int count = list.Count;
        if ((uint)index >= count)
        {
            throw new IndexOutOfRangeException();
        }
        list[index] = list[count - 1];
        list.RemoveAt(count - 1);
    }

To clearify above post.

Foreach does not allow modifying (adding/ removing) a collection while iterating.

I’m gonna try spiney199’s code out now. Thanks for letting me know how lists work in c#, I mainly code in JS.

It is no longer giving an error message, but it does not appear to be deleting the items from the list? I used Debug.Log(); to get the list length, and the number only goes up, never down. I used spiney199’s first method. Honestly, I’m probably fine with this as it is, since I doubt the items would cause any lag, since they’re only black squares and the game is pretty short.

We would have to see your code to really comment.