// 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)"); }