Beispiel #1
0
    // Load all chunks defined in loadedChunks[] array
    // true = load chunks smoothly in a spiral order
    // false = load all chunks at once. This causes high lag.
    IEnumerator LoadChunks(bool async)
    {
        // Debug
        System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
        Debug.Log("Loading chunks. (Total: " + loadDimension * loadDimension + ")");



        foreach (ChunkTransform chunkTransform in loadedChunks)
        {
            Chunk chunk;

            // Create gameObject if not exists
            if (GetChunk(chunkTransform) == null)
            {
                // Blocks
                GameObject obj = new GameObject(chunkTransform.ToString());
                obj.transform.parent   = parentOfChunks;
                obj.transform.position = chunkTransform.GetBlockPosition();

                obj.AddComponent <MeshFilter>();
                obj.AddComponent <MeshRenderer>();
                obj.AddComponent <MeshCollider>();

                chunk = obj.AddComponent <Chunk>();
                chunk.SetTransform(chunkTransform);

                // Liquids
                GameObject chunkLiquids = new GameObject("Liquids");
                chunkLiquids.transform.position = chunk.transform.position;
                chunkLiquids.transform.SetParent(chunk.transform);

                chunkLiquids.AddComponent <MeshFilter>();
                chunkLiquids.AddComponent <MeshRenderer>();

                // Customs
                GameObject chunkCustoms = new GameObject("Customs");
                chunkCustoms.transform.position = chunk.transform.position;
                chunkCustoms.transform.SetParent(chunk.transform);
                chunkCustoms.SetActive(false);
            }
            else
            {
                chunk = GetChunk(chunkTransform);
            }

            // Generate / load from file
            if (!chunk.generated)
            {
                // Check if file exists
                if (save.ChunkFileExists(chunkTransform))
                {
                    // Load chunk from file
                    chunk.chunkData = save.LoadChunk(chunkTransform);
                    chunk.decorated = true;
                }
                else
                {
                    // Generate
                    terrainGenerator.Generate(chunk);
                }

                chunk.generated = true;
            }


            // Destroy chunks that are too far away
            if (Config.UNLOAD_FAR_CHUNKS)
            {
                for (int i = 0; i < parentOfChunks.childCount; ++i)
                {
                    // Chunk's world position
                    Vector3 t = parentOfChunks.GetChild(i).position;

                    if (Vector2Int.Distance(playerChunk * 16, new Vector2Int((int)t.x, (int)t.z)) > unloadDistance * 16)
                    {
                        Chunk unload = parentOfChunks.GetChild(i).gameObject.GetComponent <Chunk>();

                        // Save if there are unsaved changes
                        if (chunk.unsaved)
                        {
                            save.SaveChunk(unload);
                        }

                        // Unload
                        Destroy(unload.gameObject);
                    }
                }
            }

            // If true, load one chunk and continue at next frame
            if (async)
            {
                yield return(null);
            }
        }


        // Link chunks
        foreach (ChunkTransform chunkTransform in renderedChunks)
        {
            Chunk chunk = GetChunk(chunkTransform);

            chunk.SetNext(
                GetChunk(chunkTransform.GetRight()),
                GetChunk(chunkTransform.GetLeft()),
                GetChunk(chunkTransform.GetFront()),
                GetChunk(chunkTransform.GetBack())
                );
        }

        // Decorate chunks
        for (int i = 0; i < renderedChunks.Length; i++)
        {
            if (GetChunk(renderedChunks[i]) != null)
            {
                Chunk chunk = GetChunk(renderedChunks[i]);

                if (!chunk.decorated && !chunk.rendered)
                {
                    terrainGenerator.Decorate(chunk);
                    chunk.decorated = true;
                }
            }

            // If true, decorate only one chunk and continue on next frame
            if (async)
            {
                yield return(null);
            }
        }

        // Render chunks
        for (int i = 0; i < parentOfChunks.childCount; ++i)
        {
            Chunk chunk = parentOfChunks.GetChild(i).gameObject.GetComponent <Chunk>();

            // Render if chunk has been modified or it is not rendered yet
            if (chunk.pendingRefresh || !chunk.rendered && chunk.generated && chunk.decorated)
            {
                chunkRenderer.Render(chunk);
                chunk.rendered       = true;
                chunk.pendingRefresh = false;
            }

            // If true, render only one chunk and continue on next frame
            if (async)
            {
                yield return(null);
            }
        }

        // Debug
        stopwatch.Stop();
        long minutes = (stopwatch.ElapsedMilliseconds / 1000) / 60;
        int  seconds = (int)((stopwatch.ElapsedMilliseconds / 1000) % 60);

        Debug.Log("Chunks rendered. (" + minutes + "m " + seconds + "s)");
    }