public virtual void UpdateChunk(TerrainChunk chunk) { if (chunk != null && chunk.IsUpdateRequired && !this.updateQueue.Contains(chunk)) { this.updateQueue.Enqueue(chunk); } }
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); }
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"); }
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; }
public virtual void MarkAsUpdateRequired(params TerrainChunk[] chunks) { for (int i = 0; i < chunks.Length; i++) { TerrainChunk chunk = chunks[i]; chunk.IsUpdateRequired = true; } }
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); }
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); }
public virtual Block GetBlockAt(Vector3Int position) { Block block = null; TerrainChunk chunk = GetChunkAt(position); if (chunk != null) { block = chunk.GetBlockAt(position, true); } return(block); }
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; }
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); } } }
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); } } }
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); } }
public virtual void UpdateChunkAt(Vector3Int position, bool isChunkPosition) { TerrainChunk chunk = GetChunkAt(position, isChunkPosition); UpdateChunk(chunk); }
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)); } }