Help designing around Collection was modified; enumeration operation may not execute.

I’ve been working on the part of my level generator that tells which rooms are connected to which other rooms. As part of this process I iterate through all of the connections in an adjacent room then for each one of them iterate through all of the connections in my room and check to see if they’re close enough for my to connect them. If so I jump down to my connect function where I update some information on one of the two connection objects and delete one of them. This throws an error however because I’m still iterating through the list of connections in the adjacent room. Does anyone have any ideas on how I can avoid this or will I have to redesign the system? Thanks for your help!

Edit: It’s throwing the error
InvalidOperationException: Collection was modified; enumeration operation may not execute.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Lets us use Concat for our lists.
using System.Linq;

/// <summary>
/// The Room Data model holds basic information about rooms and is used to differentiate between different rooms when they've been placed onto the grid.
/// </summary>
public class Room : MonoBehaviour
{
    [Tooltip("The width of the room in the X direction measured in WorldSegments")]
    public int width; //In WorldSegments. This is set in the editor.
    [Tooltip("The height of the room in the Z direction measured in WorldSegments")]
    public int height; //In WorldSegments. This is set in the editor.

    //List of connections to other rooms. This is set in the editor.
    [Tooltip("Connection GameObjects with a Connection script attached. Used to toggle walls on and off.")]
    public List<Connection> connections = new List<Connection>();

    //Position on the
    public int x; //X position of the lower left segment on the grid
    public int z; //Y position of the lower left segment on the grid
 
    //Update the connections
    //TODO: Seems to be connecting every connection.
    public void UpdateConnections(List<Room> adjacentRooms)
    {
        if (adjacentRooms.Count != 0 )
        {
            foreach (Room room in adjacentRooms)
            {
                //Iterate through every connection in every adjacent room
                //TODO: Sometimes returning a null. We're not removing the elements properly.
                foreach(Connection connection in room.connections)
                {
                    if(connection != null)
                    {
                        //Iterate through every one of the connections on this object
                        foreach (Connection myConnection in connections)
                       {
                           //If we're within 1 unit in the X/Y direction we want to connect our objects.
                            //IF possible make this value non hardcoded.
                           if(Mathf.Abs(myConnection.gameObject.transform.position.x - connection.gameObject.transform.position.x) < 3)
                           {
                               if(Mathf.Abs(myConnection.gameObject.transform.position.z - connection.gameObject.transform.position.z) < 3)
                               {
                                   Connection oldConnection = connection;
                                   //Connect the two game objects and then discard them.
                                   Connect(myConnection,oldConnection, room.connections);
                               }
                           }
                       }
                    }
                }
            }
        }
    }


    //Merge the objects the connections represent so we can turn on off both sets of connections just by toggling this one connection.
    //Then when we're finished delete one of the connections and set the saved connection as the other connection.
    //TODO: This isn't working. I'm deleting one of the connection objects being iterated through in the calling function.
    void Connect(Connection savedConnection, Connection destroyedConnection, List<Connection> updatedConnectionList)
    {
        //Merge the object lists so we know what to turn on/off when we open or close our connection.
        savedConnection.openObjects = savedConnection.openObjects.Concat(destroyedConnection.openObjects).ToArray();
        savedConnection.closeObjects = savedConnection.closeObjects.Concat(destroyedConnection.closeObjects).ToArray();

        //Our connections have found eachother. We need to remove both the connected and destroyed connection from the exterior connections list.
        GameObject[] controllerObjects = GameObject.FindGameObjectsWithTag("GameController");
        foreach(GameObject gameObject in controllerObjects)
        {
            //TODO: Make this not hardcoded
            if(gameObject.name == "WorldController")
            {
                gameObject.GetComponent<WorldGrid>().removeExteriorConnection(savedConnection);
                gameObject.GetComponent<WorldGrid>().removeExteriorConnection(destroyedConnection);
            }
        }

        savedConnection.canOpen = true;

        //overwrite the old connection
        updatedConnectionList.Remove(destroyedConnection);
        Destroy(destroyedConnection);
        updatedConnectionList.Add(savedConnection);
        destroyedConnection = savedConnection;
    }
}

You can’t modify a collection you’re iterating.

You can copy the contents of the collection into another collection (such as call ToArray on it). Note though that this copy will not be updated by any modifications to it.

Another option is if you modify it, break the loop and start over. This is necessary if you need to always be iterating the most recent version of the collection.

Thanks Lordofduct, I read through the documentation on the error after before posting here. I tried copying the variables i’m iterating through into new variables, iterating through the copies and sending the originals but I didn’t have any luck with that. I feel like I’m being daft and missing something really obvious since it’s giving me the same error.

    //Update the connections
    //TODO: Seems to be connecting every connection.
    public void UpdateConnections(List<Room> adjacentRooms)
    {
        if (adjacentRooms.Count != 0 )
        {
            foreach (Room room in adjacentRooms)
            {
                //Copy the room connections
                List<Connection> iterativeConnectionList = room.connections;
                //Iterate through every connection in every adjacent room

                foreach (Connection connection in iterativeConnectionList)
                {
                    if(connection != null)
                    {
                        //Iterate through every one of the connections on this object
                        foreach (Connection myConnection in connections)
                       {
                           //If we're within 1 unit in the X/Y direction we want to connect our objects.
                            //IF possible make this value non hardcoded.
                           if(Mathf.Abs(myConnection.gameObject.transform.position.x - connection.gameObject.transform.position.x) < 3)
                           {
                               if(Mathf.Abs(myConnection.gameObject.transform.position.z - connection.gameObject.transform.position.z) < 3)
                               {
                                   Connection oldConnection = connection;
                                    Connection savedConnection = myConnection;
                                   //Connect the two game objects and then discard them.
                                   //Connect(savedConnection, oldConnection, room.connections);
                               }
                           }
                       }
                    }
                }
            }
        }
    }


    //Merge the objects the connections represent so we can turn on off both sets of connections just by toggling this one connection.
    //Then when we're finished delete one of the connections and set the saved connection as the other connection.
    //TODO: This isn't working. I'm deleting one of the connection objects being iterated through in the calling function.
    void Connect(Connection savedConnection, Connection destroyedConnection, List<Connection> updatedConnectionList)
    {
        //Merge the object lists so we know what to turn on/off when we open or close our connection.
        savedConnection.openObjects = savedConnection.openObjects.Concat(destroyedConnection.openObjects).ToArray();
        savedConnection.closeObjects = savedConnection.closeObjects.Concat(destroyedConnection.closeObjects).ToArray();

        //Our connections have found eachother. We need to remove both the connected and destroyed connection from the exterior connections list.
        GameObject[] controllerObjects = GameObject.FindGameObjectsWithTag("GameController");
        foreach(GameObject gameObject in controllerObjects)
        {
            //TODO: Make this not hardcoded
            if(gameObject.name == "WorldController")
            {
                gameObject.GetComponent<WorldGrid>().removeExteriorConnection(savedConnection);
                gameObject.GetComponent<WorldGrid>().removeExteriorConnection(destroyedConnection);
            }
        }

        savedConnection.canOpen = true;

        //overwrite the old connection
        updatedConnectionList.Remove(destroyedConnection);
        Destroy(destroyedConnection);
        updatedConnectionList.Add(savedConnection);
        destroyedConnection = savedConnection;
    }
}

hey i know this is old. but how would you break the loop and start over? in my game there is a list of enemies that the player is constantly checking the distance between them. but if and enemy “dies” or is spawned the i need to add/remove the enemy from the list.

in the foreach (GameObject enemy in enemies){…} i am checking if the enemy has a component, then if it does then to check if isDead is true. if isDead then enemies.Remove(enemy);

right now it works how i want but i get this error. so yeah how would one “break the loop and start over?”