/// <summary> /// Adds chunk data to the world /// </summary> /// <param name="chunkData"></param> public void AddChunkData(ChunkDataPacket chunkData) { lock (_chunks) { // if the chunk already exists, add data // otherwise, make a new chunk var existingChunk = _chunks.Find(c => c.Position.Equals(chunkData.Position)); if (existingChunk != null) // chunk already exists { if (chunkData.GroundUpContinuous) { Debug.LogWarning($"Packet data for chunk at {chunkData.Position} tried to load GroundUpContinuous for already loaded chunk!"); return; } existingChunk.AddChunkData(chunkData); ChunkRenderer.MarkChunkForRegeneration(existingChunk); } else { Chunk chunk = new Chunk(chunkData, this); _chunks.Add(chunk); ChunkRenderer.AddChunk(chunk); } } }
/// <summary> /// Adds chunk data to the world /// </summary> /// <param name="chunkData"></param> public IEnumerator AddChunkDataCoroutine(ChunkDataPacket chunkData) { Chunk chunk; lock (_chunks) { // if the chunk already exists, add data // otherwise, make a new chunk chunk = _chunks.Find(c => c.Position.Equals(chunkData.Position)); if (chunk != null) // chunk already exists { if (chunkData.GroundUpContinuous) { Debug.LogWarning($"Packet data for chunk at {chunkData.Position} tried to load GroundUpContinuous for already loaded chunk!"); yield break; } } else { // need to create a new chunk chunk = new Chunk(chunkData.ChunkX, chunkData.ChunkZ, this); _chunks.Add(chunk); ChunkRenderer.AddChunk(chunk); } } while (_packetDecodeTasks.Count >= SystemInfo.processorCount) { yield return(null); } // add chunk data to chunk in another thread var task = Task.Run(() => { Profiler.BeginThreadProfiling("Add chunk data", "chunk decoder worker"); Profiler.BeginSample($"Add chunk data {chunk.ToString()}"); chunk.AddChunkData(chunkData); Profiler.EndSample(); Profiler.EndThreadProfiling(); }); _packetDecodeTasks.Add(task); // wait for task to complete while (!task.IsCompleted) { yield return(null); } _packetDecodeTasks.Remove(task); // check for exceptions if (task.IsFaulted) { throw task.Exception; } // regenerate chunk sections /* we don't use the bitmask provided in the packet here becase we want * to "render" all chunks, including empty ones, so that the game * knows they exist and aren't unloaded * * plus, the renderer won't render chunks above the bitmask provided in * this packet anyways due to the Chunk.MaxHeight property * */ ChunkRenderer.MarkChunkForRegeneration(chunk, ChunkRenderer.ALL_SECTIONS); }