Пример #1
0
        public void ManageChunks()
        {
            if (currentChunk == null)
            {
                currentChunk = new Chunk()
                {
                    coords = currentCoords
                };
            }

            int N = Game.GameConfig.renderDistance;
            int xmin = (int)currentCoords.x - N;
            int ymin = (int)currentCoords.y - N;
            int zmin = (int)currentCoords.z - N;
            int xmax = (int)currentCoords.x + N;
            int ymax = (int)currentCoords.y + N;
            int zmax = (int)currentCoords.z + N;


            List<Vector3> results = new List<Vector3>();
            for (int x = xmin; x <= xmax; x++)
            {
                for (int y = Mathf.Max(ymin, -x - zmax); y <= Mathf.Min(ymax, -x - zmin); y++)
                {
                    int z = -x - y;
                    results.Add(new Vector3(x, y, z));
                }
            }

            /// This code has been created by the awesome JohnyCilhokla
            /// for an old version of Koxel. I (Pixel) edited to make it work
            /// for the latest version.
            /// Thank you so much, Johny! :D ❤
            /// https://twitter.com/JohnyCilohokla

            foreach (Vector3 coords in results)
            {
                bool create = false;
                if (chunksStore.ContainsKey(coords))
                {
                    ChunkInfo chunkInfo = chunksStore[coords];
                    lock (unloadChunks)
                    {
                        if (Monitor.TryEnter(chunkInfo, 0))
                        {
                            try
                            {
                                if (chunkInfo.chunk == null && chunkInfo.data == null || (!chunkInfo.isLoaded && !chunkInfo.isLoading))
                                {
                                    create = true;
                                }
                                else if (chunkInfo.isUnloading) // chunk is queued to be unloaded
                                {
                                    chunkInfo.isUnloading = false; // remove unload flag
                                    unloadChunks.Remove(chunkInfo); // remove from the unload queue
                                }
                            }
                            finally
                            {
                                Monitor.Exit(chunkInfo);
                            }
                        }
                    }
                }
                else
                {
                    create = true;
                }
                if (create)
                {
                    ChunkData data;
                    /// load the chunk data here
                    /// this will save the main thread from doing that
                    /// you could/should also generate the chunks here and save the generated data
                    /// (then just setup the tiles/create objects in the main thread)
                    if (Game.SaveManager.IsChunkSaved(coords))
                    {
                        data = Game.SaveManager.LoadChunk(coords);
                    }
                    else
                    {
                        data = new ChunkData(coords);
                    }

                    ChunkInfo chunkInfo = new ChunkInfo(data);
                    chunksStore[coords] = chunkInfo; // add to the chunk store map

                    lock (loadChunks)
                    {
                        chunkInfo.isLoading = true; // add load flag
                        loadChunks.Add(chunkInfo); // add to the load queue
                    }
                }
            }

            List<Vector2> removals = new List<Vector2>();
            var it = chunksStore.GetEnumerator();
            while (it.MoveNext()) // loop through each chunk 
            {
                Vector2 pos = it.Current.Key;
                ChunkInfo chunkInfo = it.Current.Value;

                if (Monitor.TryEnter(chunkInfo, 0))
                {
                    try
                    {
                        if ((chunkInfo.isLoaded && !chunkInfo.isUnloading) || (!chunkInfo.isLoaded && chunkInfo.isLoading))
                        {
                            if (pos.x < xmin - 1 || pos.x > xmax + 1 || pos.y < Mathf.Max(ymin, -pos.x - zmax) - 1 || pos.y > Mathf.Min(ymax, -pos.x - zmin) + 1) // check if the chunk it outside of the "view"
                            {
                                if (chunkInfo.isLoaded)
                                {
                                    lock (unloadChunks)
                                    {
                                        chunkInfo.isUnloading = true; // add unload flag
                                        unloadChunks.Add(chunkInfo); // add to the unload queue
                                    }
                                }
                                else
                                {
                                    lock (loadChunks)
                                    {
                                        chunkInfo.isLoading = false; // remove load flag
                                        loadChunks.Remove(chunkInfo); // remove from the load queue
                                    }
                                }
                            }
                        }

                        if (chunkInfo.data == null && chunkInfo.chunk == null)
                        {
                            removals.Add(pos);
                        }
                    }
                    finally
                    {
                        Monitor.Exit(chunkInfo);
                    }
                }
            }
            foreach (Vector2 removal in removals)
            {
                chunksStore.Remove(removal);
            }

        }
Пример #2
0
 public void RemoveChunk(Chunk chunk)
 {
     Chunks.Remove(chunk.coords);
     Game.ObjectPooler.PoolObject(chunk.gameObject);
 }