Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

cloning a list of references? Collection was modified error.

Discussion in 'Scripting' started by Nanako, Feb 24, 2015.

  1. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    i'm doing stuff with an list where it might change partway through, aand that's causing errors. so my simple solution is to clone the array before i start operating on it, with the idea being to maintain a copy of the collection that isn't for using in the loop ( still operate on the original)

    This doesn't seem to be fixing it though, and i'm not sure why, but i suspect it might be a quirk of lists i'm not aware of:

    The situation i have is a big grid of objects. I call StartReverberation on the first one to initiate a loop, and it then calls reverbforcechunk on all those nearby it. And thehn those call it on their neighbors and so on, until ive either checked all objects or the force falls too low



    My function where i clone and do stuff with the array:

    Code (CSharp):
    1. void StartReverberation(Vector3 hitpoint, float force)
    2.     {
    3.         reverbData = new Reverberation(this, FracturedObjectSource, ChildChunkIndex, hitpoint);
    4.         List<AdjacencyInfo> templist = ListAdjacentChunks;
    5.         foreach (AdjacencyInfo temp in templist)
    6.         {
    7.             temp.chunk.ReverbForceChunk(force, hitpoint, reverbData);
    8.         }
    9.         ProcessTerminalAction();
    10.      
    11.     }

    It should be noted that this stuff is kind of recursive. ReverbForceChunk will call itself severaltimes (but on different objects.) so this object won't finish a single loop iteration until a lot of deeper layers have iterated through their own entire list.

    Here's it for comparison. Not it has a failsafe tpo prevent being called on the same chunk more than once per overall operation. Also note that ReverbForcechunk doesn't have the list duplication yet, since i've not even gotten it working in the initial script

    Code (CSharp):
    1.     public void ReverbForceChunk(float initialForce,  Vector3 Origin, Reverberation reverbInfo)
    2.     {
    3.         float distance = (Origin - transform.position).magnitude;
    4.         float thisForce = initialForce / Mathf.Pow(2, (distance / ForceHalfLife));//Calculate the force applied to this object, based on half life and origin
    5.         ForceChunk(thisForce, Origin, false);
    6.         reverbInfo.chunks[ChildChunkIndex] = this;
    7.         foreach (AdjacencyInfo temp in ListAdjacentChunks)
    8.         {
    9.             if (!(reverbInfo.chunks[temp.chunk.ChildChunkIndex]))//Here we check if the chunk in question is already in the reverb info. If it is not, then we do stuff
    10.             {
    11.                 temp.chunk.ReverbForceChunk(initialForce, Origin, reverbInfo);
    12.             }
    13.         }
    14.  
    15.         ProcessTerminalAction();
    16.         reverbInfo.processedFlags[ChildChunkIndex] = true;
    17.     }

    Now here's the error that i'm getting, which is problematic

    Code (CSharp):
    1. InvalidOperationException: Collection was modified; enumeration operation may not execute.
    2. System.Collections.Generic.List`1+Enumerator[FracturedChunk+AdjacencyInfo].VerifyState () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:778)
    3. System.Collections.Generic.List`1+Enumerator[FracturedChunk+AdjacencyInfo].MoveNext () (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/List.cs:784)
    4. FracturedChunk.StartReverberation (Vector3 hitpoint, Single force) (at Assets/Ultimate Game Tools/Fracturing/Scripts/FracturedChunk.cs:774)
    5. FracturedChunk.ForceChunk (Single force, Vector3 hitpoint, Boolean startReverb) (at Assets/Ultimate Game Tools/Fracturing/Scripts/FracturedChunk.cs:747)
    6. CollisionForce.OnCollisionEnter (UnityEngine.Collision collision) (at Assets/Scripts/Debug/CollisionForce.cs:22)
     
    Last edited: Feb 24, 2015
  2. chilberto

    chilberto

    Joined:
    Nov 18, 2013
    Posts:
    21
    Hello Nanako,
    I am not sure exactly what the issue is but the error stems from the list being iterated by a foreach. Converting it to a foreach or while should remove the invalidoperationexceptionn.
    Cheers,
    Jeff
     
  3. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    this kind of makes sense, but its still not a good solution. if a foreach loopis throwing errors on my cloned list, then i've done the cloning wrong, surely? a different kind of loop ist still going to have problems, it just won't throw an error for them,
     
  4. Strategos

    Strategos

    Joined:
    Aug 24, 2012
    Posts:
    255
  5. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Where do you exactly clone the list?
     
  6. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    i made a little cloning function, everything works now. its cool