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;
}
}