Пример #1
0
 public virtual void UpdateChunk(TerrainChunk chunk)
 {
     if (chunk != null && chunk.IsUpdateRequired && !this.updateQueue.Contains(chunk))
     {
         this.updateQueue.Enqueue(chunk);
     }
 }
Пример #2
0
        public virtual TerrainChunk CreateChunkAt(Vector3Int position, bool isChunkPosition)
        {
            if (!isChunkPosition)
            {
                position        = ToChunkPosition(position);
                isChunkPosition = true;
            }
            TerrainChunk chunk = Instantiate <TerrainChunk>(this.currentWorld.ChunkPrefab, position, Quaternion.identity, this.chunksContainer);

            this.chunks.Add(position, chunk);
            chunk.Initialize(position);
            if (position.y == this.currentWorld.TerrainMaxHeight)
            {
                Thread thread = new Thread(() =>
                {
                    this.threadCount++;
                    this.isGenerating = true;
                    this.terrainGenerator.GenerateTerrainForChunkColumn(position);
                    this.isGenerating = false;
                    for (int y = position.y; y > this.currentWorld.TerrainMinHeight; y -= this.currentWorld.ChunkPrefab.Size.y)
                    {
                        Vector3Int chunkPosition   = new Vector3Int(position.x, y, position.z);
                        TerrainChunk chunkToUpdate = GetChunkAt(chunkPosition);
                        UpdateChunk(chunkToUpdate);
                        UpdateChunk(chunkToUpdate.RightChunk);
                        UpdateChunk(chunkToUpdate.LeftChunk);
                        UpdateChunk(chunkToUpdate.ForwardChunk);
                        UpdateChunk(chunkToUpdate.BackChunk);
                    }
                    this.threadCount--;
                });
                thread.Start();
            }
            return(chunk);
        }
Пример #3
0
        public virtual void UpdateChunks(Stopwatch stopwatch)
        {
            if (this.isGenerating)
            {
                return;
            }
            this.meshesLastFrame = 0;
            int num = Mathf.RoundToInt(this.averageFPS - this.targetFPS);

            while (this.updateQueue.Count > 0 && !this.isGenerating)
            {
                TerrainChunk chunk = this.updateQueue.Dequeue();
                if (chunk != null)
                {
                    chunk.UpdateMesh();
                    this.meshesLastFrame++;
                    if (stopwatch.ElapsedMilliseconds >= num)
                    {
                        break;
                    }
                }
            }
            //if (this.updateQueue.Count == 0 || this.isUpdatingChunks)
            //{
            //    return;
            //}
            //StartCoroutine("UpdateChunksAsync");
        }
Пример #4
0
        protected virtual IEnumerator FindChunksAndLoad()
        {
            this.isLoadingChunks = true;
            //Cycle through the array of positions
            for (int i = 0; i < this.chunkLoadOrder.Length; i++)
            {
                //Get the position of this gameobject to generate around
                Vector3Int playerPos = VoxelManager.Instance.ToChunkPosition(new Vector3Int((int)transform.position.x, (int)transform.position.y, (int)transform.position.z));

                //translate the player position and array position into chunk position
                Vector3Int newChunkPos = new Vector3Int(
                    this.chunkLoadOrder[i].x * VoxelManager.Instance.CurrentWorld.ChunkPrefab.Size.x + playerPos.x,
                    0,
                    this.chunkLoadOrder[i].z * VoxelManager.Instance.CurrentWorld.ChunkPrefab.Size.y + playerPos.z);

                //Get the chunk in the defined position
                TerrainChunk newChunk = VoxelManager.Instance.GetChunkAt(newChunkPos, true);

                //If the chunk already exists and it's already
                //rendered or in queue to be rendered continue
                if (newChunk != null)
                {
                    continue;
                }
                LoadChunkColumn(newChunkPos);
                //yield return this.waitWhileGenerating;
                yield return(CoroutineUtils.EndOfFrame);
            }
            this.isLoadingChunks = false;
        }
Пример #5
0
 public virtual void MarkAsUpdateRequired(params TerrainChunk[] chunks)
 {
     for (int i = 0; i < chunks.Length; i++)
     {
         TerrainChunk chunk = chunks[i];
         chunk.IsUpdateRequired = true;
     }
 }
Пример #6
0
 public virtual TerrainChunk[] GetAdjacentChunksAt(Vector3Int position, bool isChunkPosition)
 {
     Vector3Int[]   positions = GetAdjacentChunksPositionAt(position, isChunkPosition);
     TerrainChunk[] chunks    = new TerrainChunk[positions.Length];
     for (int i = 0; i < positions.Length; i++)
     {
         chunks[i] = GetChunkAt(positions[i], true);
     }
     return(chunks);
 }
Пример #7
0
        public virtual Block SetBlockAt(Vector3Int position, Block block, bool immediateUpdate)
        {
            Block        oldBlock = null;
            TerrainChunk chunk    = GetChunkAt(position);

            if (chunk != null)
            {
                oldBlock = chunk.SetBlockAt(position, block, true, immediateUpdate);
            }
            return(oldBlock);
        }
Пример #8
0
        public virtual Block GetBlockAt(Vector3Int position)
        {
            Block        block = null;
            TerrainChunk chunk = GetChunkAt(position);

            if (chunk != null)
            {
                block = chunk.GetBlockAt(position, true);
            }
            return(block);
        }
Пример #9
0
        protected virtual IEnumerator UpdateChunksAsync()
        {
            this.isUpdatingChunks = true;
            this.updatingChunk    = this.updateQueue.Dequeue();
            if (this.updatingChunk != null)
            {
                this.updatingChunk.UpdateMeshAsync();
                yield return(this.waitWhileUpdatingChunk);

                yield return(CoroutineUtils.EndOfFrame);
            }
            this.isUpdatingChunks = false;
        }
Пример #10
0
        protected virtual void Update()
        {
            RaycastHit hit;
            Vector3    origin = Camera.main.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0f));

            if (Physics.Raycast(origin, Camera.main.transform.forward, out hit, 100f, LayerMask.GetMask("Terrain")))
            {
                TerrainChunk chunk = hit.collider.GetComponent <TerrainChunk>();
                Debug.DrawLine(origin, hit.point, Color.red);
                Vector3Int normal          = Truncate(hit.normal);
                Vector3Int placePosition   = FloorToInt(hit.point);
                Vector3Int destroyPosition = FloorToInt(hit.point);
                if (normal.x > 0)
                {
                    destroyPosition.x -= normal.x;
                }
                if (normal.y > 0)
                {
                    destroyPosition.y -= normal.y;
                }
                if (normal.z > 0)
                {
                    destroyPosition.z -= normal.z;
                }
                if (normal.x < 0)
                {
                    placePosition.x += normal.x;
                }
                if (normal.y < 0)
                {
                    placePosition.y += normal.y;
                }
                if (normal.z < 0)
                {
                    placePosition.z += normal.z;
                }
                this.destroyHighlight.transform.position = destroyPosition;
                this.placeHighlight.transform.position   = placePosition;
                placePosition.x++;
                destroyPosition.x++;
                if (Input.GetMouseButton(0))
                {
                    VoxelManager.Instance.SetBlockAt(destroyPosition, null, true);
                }
                if (Input.GetMouseButton(1))
                {
                    VoxelManager.Instance.SetBlockAt(placePosition, new Block(this.block), true);
                }
            }
        }
Пример #11
0
 protected virtual void LoadChunkColumn(Vector3Int columnPosition)
 {
     //First create the chunk game objects in the world class
     //The world class wont do any generation when threaded chunk creation is enabled
     for (int y = VoxelManager.Instance.CurrentWorld.TerrainMinHeight; y <= VoxelManager.Instance.CurrentWorld.TerrainMaxHeight; y += VoxelManager.Instance.CurrentWorld.ChunkPrefab.Size.y)
     {
         Vector3Int   position = new Vector3Int(columnPosition.x, y, columnPosition.z);
         TerrainChunk chunk    = VoxelManager.Instance.GetChunkAt(position, true);
         if (chunk == null)
         {
             VoxelManager.Instance.CreateChunkAt(position, true);
         }
     }
 }
Пример #12
0
        public virtual void DestroyChunkAt(Vector3Int position, bool isChunkPosition)
        {
            if (!isChunkPosition)
            {
                position        = ToChunkPosition(position);
                isChunkPosition = true;
            }
            TerrainChunk chunk = GetChunkAt(position, isChunkPosition);

            if (chunk != null)
            {
                this.chunks.Remove(position);
                Destroy(chunk.gameObject);
            }
        }
Пример #13
0
        public virtual void UpdateChunkAt(Vector3Int position, bool isChunkPosition)
        {
            TerrainChunk chunk = GetChunkAt(position, isChunkPosition);

            UpdateChunk(chunk);
        }
Пример #14
0
        public virtual Block SetBlockAt(Vector3Int position, Block block, bool worldPosition, bool immediateUpdate)
        {
            Vector3Int blockPosition = position;

            if (worldPosition)
            {
                blockPosition = position - this.position;
            }
            else
            {
                position = position + this.position;
            }
            if (blockPosition.x >= 0 && blockPosition.x < this.size.x && blockPosition.y >= 0 && blockPosition.y < this.size.y && blockPosition.z >= 0 && blockPosition.z < this.size.z)
            {
                Block oldBlock = this.blocks[blockPosition.x, blockPosition.y, blockPosition.z];
                this.blocks[blockPosition.x, blockPosition.y, blockPosition.z] = block;
                this.isUpdateRequired = true;
                if (immediateUpdate)
                {
                    this.UpdateMesh();
                }
                if (blockPosition.x == 0)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position - new Vector3Int(1, 0, 0), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                if (blockPosition.x == this.size.x - 1)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position + new Vector3Int(1, 0, 0), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                if (blockPosition.y == 0)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position - new Vector3Int(0, 1, 0), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                if (blockPosition.y == this.size.y - 1)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position + new Vector3Int(0, 1, 0), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                if (blockPosition.z == 0)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position - new Vector3Int(0, 0, 1), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                if (blockPosition.z == this.size.z - 1)
                {
                    TerrainChunk chunk = VoxelManager.Instance.GetChunkAt(position + new Vector3Int(0, 0, 1), false);
                    if (chunk != null)
                    {
                        chunk.IsUpdateRequired = true;
                        if (immediateUpdate)
                        {
                            chunk.UpdateMesh();
                        }
                    }
                }
                return(oldBlock);
            }
            else
            {
                return(VoxelManager.Instance.SetBlockAt(position, block, immediateUpdate));
            }
        }