コード例 #1
0
ファイル: World.cs プロジェクト: tuita520/Hephaestus
 // Chunk Creation / Generation / Update / Degeneration Loop
 private void UpdateChunks()
 {
     // If starting zone is initialized and player doesn't already exist, try instantiating player
     if (this.starterChunksInitialized && !GameManager.PlayerLoaded())
     {
         Int3 PlayerStartPos      = this.GetPlayerStartPosition(this.WorldStartPos);
         Int3 PlayerStartChunkPos = PlayerStartPos;
         PlayerStartChunkPos.WorldCoordsToChunkCoords();
         Chunk      chunk = this.GetChunk(PlayerStartChunkPos);
         GameObject go    = chunk.GO;
         GameManager.Instance.StartPlayer(PlayerStartPos.GetVec3(), go);
     }
     // After initial chunk generation and player loaded into world, continuously generate Chunks around player and degenerate Chunks too far away
     if (this.starterChunksInitialized && GameManager.PlayerLoaded())
     {
         // Get current player position
         Int3 currentPlayerPos = new Int3(GameManager.Instance.PlayerPos);
         // Iterate through Loaded Chunks and Degenerate if they are too far from current player position
         foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
         {
             Int3 chunkPos = chunk.Value.Pos;
             chunkPos.ChunkCoordsToWorldCoords();
             if (Vector3.Distance(chunkPos.GetVec3(), currentPlayerPos.GetVec3()) >= (renderDistance * this.distanceToDegenerateMultiplier * Chunk.ChunkSize))
             {
                 if (!this.chunksToRemove.Contains(chunk.Key))
                 {
                     chunk.Value.Degenerate();
                 }
             }
         }
         // Remove degenerated Chunks from loaded Chunks list
         this.RemoveChunks();
         // Continuously generate Chunks around player
         for (int x = -RenderDistanceFirstPass; x < RenderDistanceFirstPass; x++)
         {
             for (int y = -RenderDistanceFirstPass; y < RenderDistanceFirstPass; y++)
             {
                 for (int z = -RenderDistanceFirstPass; z < RenderDistanceFirstPass; z++)
                 {
                     Int3 xyz = new Int3(0, 0, 0);
                     xyz.SetPos(x, y, z);
                     Int3 newChunkPos = currentPlayerPos;
                     newChunkPos += xyz * Chunk.ChunkSize;
                     newChunkPos.WorldCoordsToChunkCoords();
                     // If currently pointed to Chunk hasn't already been added to World
                     if (!this.ChunkExists(newChunkPos))
                     {
                         // If save file exists for Chunk, read chunk data from file and add Chunk to World
                         if (System.IO.File.Exists(FileManager.GetChunkString(newChunkPos)))
                         {
                             try
                             {
                                 Chunk chunk = new Chunk(newChunkPos, Serializer.DeserializeFromFile <int[, , ]>(FileManager.GetChunkString(newChunkPos)));
                                 this.loadedChunks.Add(newChunkPos, chunk);
                             }
                             catch (Exception e)
                             {
                                 Debug.Log(e.ToString());
                                 Logger.Log(e);
                             }
                         }
                         // If no save file for chunk, generate new Chunk and add to World
                         else
                         {
                             Chunk chunk = new Chunk(newChunkPos);
                             this.loadedChunks.Add(newChunkPos, chunk);
                         }
                     }
                 }
             }
         }
         // Generate blocks for all loaded Chunks
         foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
         {
             TaskFactory.StartNew(() => chunk.Value.Start());
         }
         // Generate meshes for all loaded Chunks
         foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
         {
             Int3 chunkPos = chunk.Value.Pos;
             chunkPos.ChunkCoordsToWorldCoords();
             if (Vector3.Distance(chunkPos.GetVec3(), currentPlayerPos.GetVec3()) <= (renderDistance * Chunk.ChunkSize))
             {
                 if (this.ChunkExists(chunk.Value.NegXNeighbor) && this.ChunkExists(chunk.Value.PosXNeighbor) &&
                     this.ChunkExists(chunk.Value.NegYNeighbor) && this.ChunkExists(chunk.Value.PosYNeighbor) &&
                     this.ChunkExists(chunk.Value.NegZNeighbor) && this.ChunkExists(chunk.Value.PosZNeighbor))
                 {
                     // Before update, if Chunk has been set that its neighbors need to update, tell those neighbors they need to update
                     // Neighbors will need to update meshes if a block is changed at the intersection of chunks to avoid holes between chunks
                     if (chunk.Value.NeedToUpdateNegXNeighbor)
                     {
                         this.GetChunk(chunk.Value.NegXNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdateNegXNeighbor = false;
                     }
                     if (chunk.Value.NeedToUpdatePosXNeighbor)
                     {
                         this.GetChunk(chunk.Value.PosXNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdatePosXNeighbor = false;
                     }
                     if (chunk.Value.NeedToUpdateNegYNeighbor)
                     {
                         this.GetChunk(chunk.Value.NegYNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdateNegYNeighbor = false;
                     }
                     if (chunk.Value.NeedToUpdatePosYNeighbor)
                     {
                         this.GetChunk(chunk.Value.PosYNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdatePosYNeighbor = false;
                     }
                     if (chunk.Value.NeedToUpdateNegZNeighbor)
                     {
                         this.GetChunk(chunk.Value.NegZNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdateNegZNeighbor = false;
                     }
                     if (chunk.Value.NeedToUpdatePosZNeighbor)
                     {
                         this.GetChunk(chunk.Value.PosZNeighbor).NeedToUpdate = true;
                         chunk.Value.NeedToUpdateNegZNeighbor = false;
                     }
                     TaskFactory.StartNew(() => chunk.Value.Update());
                 }
             }
         }
         foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
         {
             GameManager.Instance.RegisterDelegate(new Action(() => chunk.Value.OnUnityUpdate()));
         }
     }
 }
コード例 #2
0
ファイル: World.cs プロジェクト: tuita520/Hephaestus
        // Initialize Starter Zone Chunks
        private void InitializeStarterZone()
        {
            // Starting zone Chunk initialization, for all Chunks within Rendering Distance First Pass
            // Check if chunk exists in save file, if so get from file, if not Generate new Chunk
            Int3 startingChunkPos = this.WorldStartPos;

            startingChunkPos.WorldCoordsToChunkCoords();
            Int3 xyz = new Int3(0, 0, 0);

            for (int x = -RenderDistanceFirstPass; x < RenderDistanceFirstPass; x++)
            {
                for (int y = -RenderDistanceFirstPass; y < RenderDistanceFirstPass; y++)
                {
                    for (int z = -RenderDistanceFirstPass; z < RenderDistanceFirstPass; z++)
                    {
                        xyz.SetPos(x, y, z);
                        Int3 newChunkPos = this.WorldStartPos;
                        newChunkPos += xyz * Chunk.ChunkSize;
                        newChunkPos.WorldCoordsToChunkCoords();
                        // x,y,z for loop makes a cube of chunks of renderDistanceFirstPass^3, distance function below cuts that into a sphere (instead of cube), saves 30+% in generation time
                        if (Vector3.Distance(newChunkPos.GetVec3(), startingChunkPos.GetVec3()) <= RenderDistanceFirstPass)
                        {
                            // If save file exists for Chunk, read chunk data from file and add Chunk to World
                            if (System.IO.File.Exists(FileManager.GetChunkString(newChunkPos)))
                            {
                                try
                                {
                                    Chunk chunk = new Chunk(newChunkPos, Serializer.DeserializeFromFile <int[, , ]>(FileManager.GetChunkString(newChunkPos)));
                                    this.loadedChunks.Add(newChunkPos, chunk);
                                }
                                catch (Exception e)
                                {
                                    Debug.Log(e.ToString());
                                    Logger.Log(e);
                                }
                            }
                            // If no save file for chunk, generate new Chunk and add to World
                            else
                            {
                                Chunk chunk = new Chunk(newChunkPos);
                                this.loadedChunks.Add(newChunkPos, chunk);
                            }
                        }
                    }
                }
            }
            // Generate blocks for each of the loaded Chunks
            foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
            {
                chunk.Value.Start();
            }
            Debug.Log($@"{GameManager.Time}: Finished Starter Zone Generation Initialization");
            Logger.Log($@"{GameManager.Time}: Finished Starter Zone Generation Initialization");
            // Generate mesh for each of the loaded Chunks (check if they have all neighbors meshed to avoid broken meshes at Chunk intersections)
            foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
            {
                if (this.ChunkExists(chunk.Value.NegXNeighbor) && this.ChunkExists(chunk.Value.PosXNeighbor) &&
                    this.ChunkExists(chunk.Value.NegYNeighbor) && this.ChunkExists(chunk.Value.PosYNeighbor) &&
                    this.ChunkExists(chunk.Value.NegZNeighbor) && this.ChunkExists(chunk.Value.PosZNeighbor))
                {
                    chunk.Value.Update();
                }
            }
            Debug.Log($@"{GameManager.Time}: Finished Starter Zone Meshing Initialization");
            Logger.Log($@"{GameManager.Time}: Finished Starter Zone Meshing Initialization");
            // Generate GameObject and MeshRenderer for each of the loaded Chunks
            foreach (KeyValuePair <Int3, Chunk> chunk in this.loadedChunks)
            {
                chunk.Value.OnUnityUpdate();
            }
            this.starterChunksInitialized = true;
            Debug.Log($@"{GameManager.Time}: Finished Starter Zone Rendering Initialization");
            Logger.Log($@"{GameManager.Time}: Finished Starter Zone Rendering Initialization");
        }