Пример #1
0
 // Remove Chunk from world, given Chunk Position
 public void AddChunkToRemoveList(Int3 _chunkPos)
 {
     this.chunksToRemove.Add(_chunkPos);
     //Debug.Log($@"{GameManager.time}: Added Chunk to remove list: C_{chunkPos.x}_{chunkPos.y}_{chunkPos.z}");
     //Logger.Log($@"{GameManager.time}: Added Chunk to remove list: C_{chunkPos.x}_{chunkPos.y}_{chunkPos.z}");
 }
Пример #2
0
 // 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()));
         }
     }
 }
Пример #3
0
        // Create Mesh for Cube, given Chunk Internal Coords as int(x,y,z), Block 3D Array blocks, Block block, UVMaps as Vector2 Arrays, and Chunk Coords as int(PosX, PosY, PosZ)
        // Draw Grass Block
        public static MeshData DrawCube(int _x, int _y, int _z, Block[,,] _blocks, Block _block, Block.BlockFaceStyle _style, Vector2[] _uvMap0, Vector2[] _uvMap1, Vector2[] _uvMap2, Vector2[] _uvMap3, Vector2[] _uvMap4, Vector2[] _uvMap5, Int3 _chunkPos)
        {
            MeshData data = new MeshData();
            Int3     pos  = new Int3(_x, _y, _z);

            pos.ChunkInternalCoordsToWorldCoords(_chunkPos);
            // Bottom Face
            bool bottomVis = CheckVis(_x, _y, _z, pos, _blocks, Side.Bottom);
            bool topVis    = CheckVis(_x, _y, _z, pos, _blocks, Side.Top);
            bool frontVis  = CheckVis(_x, _y, _z, pos, _blocks, Side.Front);
            bool backVis   = CheckVis(_x, _y, _z, pos, _blocks, Side.Back);
            bool leftVis   = CheckVis(_x, _y, _z, pos, _blocks, Side.Left);
            bool rightVis  = CheckVis(_x, _y, _z, pos, _blocks, Side.Right);

            if (bottomVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    data.Merge(new MeshData(
                                   bottomFaceVerts,
                                   bottomFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap3[0],
                        _uvMap3[1],
                        _uvMap3[2],
                        _uvMap3[3]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   bottomFaceVerts,
                                   bottomFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[0],
                        _uvMap0[1],
                        _uvMap0[2],
                        _uvMap0[3]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   bottomFaceVerts,
                                   bottomFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[0],
                        _uvMap0[1],
                        _uvMap0[2],
                        _uvMap0[3]
                    }));
                }
            }
            // Top Face
            if (topVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    data.Merge(new MeshData(
                                   topFaceVerts,
                                   topFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[0],
                        _uvMap0[1],
                        _uvMap0[2],
                        _uvMap0[3]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   topFaceVerts,
                                   topFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[0],
                        _uvMap0[1],
                        _uvMap0[2],
                        _uvMap0[3]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   topFaceVerts,
                                   topFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[0],
                        _uvMap0[1],
                        _uvMap0[2],
                        _uvMap0[3]
                    }));
                }
            }
            // Front Face
            if (frontVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    if (topVis)
                    {
                        data.Merge(new MeshData(
                                       frontFaceVerts,
                                       frontFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap1[2],
                            _uvMap1[0],
                            _uvMap1[3],
                            _uvMap1[1]
                        }));
                    }
                    else
                    {
                        data.Merge(new MeshData(
                                       frontFaceVerts,
                                       frontFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap3[2],
                            _uvMap3[0],
                            _uvMap3[3],
                            _uvMap3[1]
                        }));
                    }
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   frontFaceVerts,
                                   frontFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap1[2],
                        _uvMap1[0],
                        _uvMap1[3],
                        _uvMap1[1]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   frontFaceVerts,
                                   frontFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[2],
                        _uvMap0[0],
                        _uvMap0[3],
                        _uvMap0[1]
                    }));
                }
            }
            // Back Face
            if (backVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    if (topVis)
                    {
                        data.Merge(new MeshData(
                                       backFaceVerts,
                                       backFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap1[2],
                            _uvMap1[0],
                            _uvMap1[3],
                            _uvMap1[1]
                        }));
                    }
                    else
                    {
                        data.Merge(new MeshData(
                                       backFaceVerts,
                                       backFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap3[2],
                            _uvMap3[0],
                            _uvMap3[3],
                            _uvMap3[1]
                        }));
                    }
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   backFaceVerts,
                                   backFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap1[2],
                        _uvMap1[0],
                        _uvMap1[3],
                        _uvMap1[1]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   backFaceVerts,
                                   backFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[2],
                        _uvMap0[0],
                        _uvMap0[3],
                        _uvMap0[1]
                    }));
                }
            }
            // Left Face
            if (leftVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    if (topVis)
                    {
                        data.Merge(new MeshData(
                                       leftFaceVerts,
                                       leftFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap1[2],
                            _uvMap1[0],
                            _uvMap1[3],
                            _uvMap1[1]
                        }));
                    }
                    else
                    {
                        data.Merge(new MeshData(
                                       leftFaceVerts,
                                       leftFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap3[2],
                            _uvMap3[0],
                            _uvMap3[3],
                            _uvMap3[1]
                        }));
                    }
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   leftFaceVerts,
                                   leftFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap1[2],
                        _uvMap1[0],
                        _uvMap1[3],
                        _uvMap1[1]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   leftFaceVerts,
                                   leftFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[2],
                        _uvMap0[0],
                        _uvMap0[3],
                        _uvMap0[1]
                    }));
                }
            }
            // Right Face
            if (rightVis)
            {
                if (_style == Block.BlockFaceStyle.GrassStyle)
                {
                    if (topVis)
                    {
                        data.Merge(new MeshData(
                                       rightFaceVerts,
                                       rightFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap1[2],
                            _uvMap1[0],
                            _uvMap1[3],
                            _uvMap1[1]
                        }));
                    }
                    else
                    {
                        data.Merge(new MeshData(
                                       rightFaceVerts,
                                       rightFaceDrawOrder,
                                       new Vector2[]
                        {
                            _uvMap3[2],
                            _uvMap3[0],
                            _uvMap3[3],
                            _uvMap3[1]
                        }));
                    }
                }
                else if (_style == Block.BlockFaceStyle.LogStyle)
                {
                    data.Merge(new MeshData(
                                   rightFaceVerts,
                                   rightFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap1[2],
                        _uvMap1[0],
                        _uvMap1[3],
                        _uvMap1[1]
                    }));
                }
                else if (_style == Block.BlockFaceStyle.UniversalStyle)
                {
                    data.Merge(new MeshData(
                                   rightFaceVerts,
                                   rightFaceDrawOrder,
                                   new Vector2[]
                    {
                        _uvMap0[2],
                        _uvMap0[0],
                        _uvMap0[3],
                        _uvMap0[1]
                    }));
                }
            }
            data.AddPos(new Vector3(_x - 0.5f, _y - 0.5f, _z - 0.5f));
            return(data);
        }
Пример #4
0
        // 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");
        }
Пример #5
0
 // Checks visibility of given face
 private static bool CheckVis(int _x, int _y, int _z, Int3 _position, Block[,,] _blocks, Side _side)
 {
     if (_side == Side.Bottom)
     {
         if (_y > 0)
         {
             Block block = _blocks[_x, _y - 1, _z];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_y == 0)
         {
             Int3 pos = _position;
             pos.AddPos(0, -1, 0);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
     else if (_side == Side.Top)
     {
         if (_y < Chunk.ChunkSize - 1)
         {
             Block block = _blocks[_x, _y + 1, _z];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_y == Chunk.ChunkSize - 1)
         {
             Int3 pos = _position;
             pos.AddPos(0, 1, 0);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
     else if (_side == Side.Front)
     {
         if (_x > 0)
         {
             Block block = _blocks[_x - 1, _y, _z];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_x == 0)
         {
             Int3 pos = _position;
             pos.AddPos(-1, 0, 0);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
     else if (_side == Side.Back)
     {
         if (_x < Chunk.ChunkSize - 1)
         {
             Block block = _blocks[_x + 1, _y, _z];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_x == Chunk.ChunkSize - 1)
         {
             Int3 pos = _position;
             pos.AddPos(1, 0, 0);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
     else if (_side == Side.Left)
     {
         if (_z > 0)
         {
             Block block = _blocks[_x, _y, _z - 1];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_z == 0)
         {
             Int3 pos = _position;
             pos.AddPos(0, 0, -1);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
     else // Side.Right
     {
         if (_z < Chunk.ChunkSize - 1)
         {
             Block block = _blocks[_x, _y, _z + 1];
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         else if (_z == Chunk.ChunkSize - 1)
         {
             Int3 pos = _position;
             pos.AddPos(0, 0, 1);
             Block block = World.Instance.GetBlockFromWorldCoords(pos);
             return(block.IsTransparent || block.IsSemiTransparent);
         }
         return(false);
     }
 }