1
\$\begingroup\$

First, some context: I am developing a chunk loading system for unity. I load all the chunks as prefabs from disk to an array as a cache. When I need to load a chunk, I instantiate it from the cache into the world.
The problem is that when deleting gameobjects from the world (using the destroy method) to unload them, it also destroys the cached copy meaning that I can't instantiate it back later.
I've done some of my own research and I have found that some time after I initially cached the gameobjects and instantiated them into the scene for the first time, the hash codes of both the cached and world gameobjects change to become the same thing. This occurs while the editor isn't playing and no other scripts are running.

Hashcodes change by themselves

Here is some code:

 void ImportChunks ()
{
    //Reset All Chunks
    //prefabs = new List<GameObject>();
    prefabs.Clear ();

    prefSorted = new List<List<List<GameObject>>> ();

    //Fill the list
    prefSorted = Enumerable.Range (0, Layers).Select (l =>
        Enumerable.Range (0, GridXSize).Select (h =>
            Enumerable.Range (0, GridYSize).Select (w => 
                new GameObject ()).ToList ()).ToList ()).ToList (); 

    Debug.Log (prefSorted.Count + " layers");
    Debug.Log (prefSorted [0].Count + " x");
    Debug.Log (prefSorted [0] [0].Count + " y");

    //Load Chunks From Disk
    string[] pref = AssetDatabase.FindAssets ("@", new string[]{ PrefabDir });
    int d = 0;
    foreach (string prefa in pref)
    {
        //Load chunk from disk
        GameObject n = ((GameObject)AssetDatabase.LoadAssetAtPath (AssetDatabase.GUIDToAssetPath (prefa), typeof(GameObject)));

        //Put it into the cache array
        int[] pos = GetPos (n.name);
        prefSorted [pos [0]] [pos [1]] [pos [2]] = n;

        d++;
    }

    //Add all of our children to the loaded array
    HashSet<GameObject> children = new HashSet<GameObject> ();

    for (int i = 0; i < this.transform.childCount; i++)
    {
        children.Add (this.transform.GetChild (i).gameObject);
    }

    loaded = children;
}

public GameObject LoadChunk (int l, int x, int y)
{
    //We have an array containing a reference to all the currently loaded chunks.
    //Here we find the chunk which is already at the coordinates where we want to load the new chunk.
    //BTW naming convention is x-y@l-lv
    GameObject old = loaded.FirstOrDefault (i => i.name.Split ("@" [0]) [0] == x + "-" + y);
    if (old != null)
    {
        if (old.name.Split ("@" [0]) [1].Split ("-" [0]) [0] == l.ToString ())
            return null;

        //Destroy the object and remove it from the array of REFERENCED objects
        Destroy (old);
        loaded.Remove (old);
    }

    //Make the new chunk
    //prefSorted is a cache of all chunks so they can be instantiated
    GameObject newChunk = Instantiate (prefSorted [l] [x] [y]);

    newChunk.transform.SetParent (this.transform);
    loaded.Add (newChunk);
    newChunk.transform.localPosition = new Vector3 (x * GridScale.x, 0, y * GridScale.y);

    return newChunk;
}

Thanks for everybody's help in advance. If you have any questions, leave a comment and I'll update the post. Thanks,
-Thomas

\$\endgroup\$
  • 3
    \$\begingroup\$ I recommend de-butchering your code to create a minimal, complete, verifiable example of the problem. The code sample you've shown includes a lot of code you've commented out, but not all of the code visible in your debug log, which means there's a lot of guesswork involved in trying to reproduce the issue. The less we have to guess, the faster and higher quality answers you're likely to get. \$\endgroup\$ – DMGregory Oct 13 '17 at 23:21
  • \$\begingroup\$ I hope I have improved the code sufficiently to help you. \$\endgroup\$ – Thomas Mathieson Oct 15 '17 at 9:27
  • \$\begingroup\$ @ThomasMathieson I may be missing it, but where is your loaded variable defined. \$\endgroup\$ – Chris Oct 26 '17 at 17:23
  • \$\begingroup\$ @Chris Yes, that's my mistake, this loaded variable is being defined outside off this excerpt. it simply contains references to all the loaded find in the scene and is defined as follows: public List<GameObject> loaded = new List<GameObject>(); \$\endgroup\$ – Thomas Mathieson Oct 29 '17 at 9:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.