Hello. I seem to be having an issue where when an object gets deleted, and was an element in a list, it turns into a null element. Trying to do anything with the null element in my foreach loop causes an error that looks like this:
InvalidOperationException: Collection was modified; enumeration operation may not execute.
So I tried checking if it was null before doing anything with it, which works fine and causes no errors, but now I’m left with a null element that needs to be skipped through. So I tried deleting the null element, but for some reason that causes the same error above.
public void CheckSurroundings(){
foreach (GameObject Thing in ObjectsInSight) {
if (Thing != null) {
//Do stuff
} else {
ObjectsInSight.Remove (Thing.gameObject); //Causes error
}
}
}
Ok there are several things wrong here ^^. First of all you don’t want to use foreach when you’re going to modify the collection you’re iterating over. This will make the foreach loop to skip elements. If you want to remove elements you should iterate the list backwards. This won’t cause any issues as when you remove elements only those you already visited will be moved.
Next problem is if an object got destroyed you can’t use any of the properties the object provides as they require the object to still be “alive”. However doing “Thing.gameObject” makes not much sense as “Thing” is the gameobject.
This should work ObjectsInSight.Remove (Thing); however as i said you shouldn’t use it in a foreach loop. If the order of the elements doesn’t matter, “Remove” is unnecessary expensive as each Remove call will move all following elements one back. You can simply replace the element you want to get rid of with the last element of the list and just remove the last element. In short:
public void CheckSurroundings()
{
for (int i = ObjectsInSight - 1; i >=0; i--)
{
if (ObjectsInSight *!= null)*
{ //Do stuff } else { ObjectsInSight = ObjectsInSight[ObjectsInSight.Count - 1]; ObjectsInSight.RemoveAt(ObjectsInSight.Count-1); } } } If you want to preserve the order of the elements you could simply do: public void CheckSurroundings() { for (int i = ObjectsInSight - 1; i >=0; i–) { if (ObjectsInSight != null) { //Do stuff } else { ObjectsInSight.RemoveAt(i); } } }