/** * Generate a column of blocks in the given 2d coords inside the given Chunk. **/ protected virtual Chunk GenerateTerrain(Chunk chunk, int x, int z) { int stoneHeight = LayerStoneBase(chunk.pos.x + x, chunk.pos.z + z); stoneHeight += LayerStoneNoise(chunk.pos.x + x, chunk.pos.z + z); int dirtHeight = stoneHeight + LayerDirt(chunk.pos.x + x, chunk.pos.z + z); //CreateTreeIfValid(x, z, chunk, dirtHeight); for (int y = 0; y < Chunk.chunkSize; y++) { if (y + chunk.pos.y <= stoneHeight) { SetBlock(chunk, 1, new WorldPos(x, y, z)); if(chunk.empty){chunk.empty = false;} } else if (y + chunk.pos.y < dirtHeight) { SetBlock(chunk, 3, new WorldPos(x, y, z)); if(chunk.empty){chunk.empty = false;} } else if (y + chunk.pos.y == dirtHeight) { SetBlock(chunk, 2, new WorldPos(x, y, z)); if(chunk.empty){chunk.empty = false;} } else { SetBlock(chunk, 0, new WorldPos(x, y, z)); } } return chunk; }
/** * Get the mesh for a single block and add it to the given mesh data object. **/ public virtual MeshData GetBlockMesh(Chunk chunk, int x, int y, int z, MeshData meshData) { if(!Register.GetBlockById(chunk.GetBlock(x, y + 1, z)).IsSolid(Direction.UP)) { meshData = MeshData.CreateFaceUp(chunk, x, y, z, this, meshData, 0.5f); } if(!Register.GetBlockById(chunk.GetBlock(x, y - 1, z)).IsSolid(Direction.DOWN)) { meshData = MeshData.CreateFaceDown(chunk, x, y, z, this, meshData, 0.5f); } if(!Register.GetBlockById(chunk.GetBlock(x, y, z + 1)).IsSolid(Direction.NORTH)) { meshData = MeshData.CreateFaceNorth(chunk, x, y, z, this, meshData, 0.5f); } if(!Register.GetBlockById(chunk.GetBlock(x, y, z - 1)).IsSolid(Direction.SOUTH)) { meshData = MeshData.CreateFaceSouth(chunk, x, y, z, this, meshData, 0.5f); } if(!Register.GetBlockById(chunk.GetBlock(x + 1, y, z)).IsSolid(Direction.EAST)) { meshData = MeshData.CreateFaceEast(chunk, x, y, z, this, meshData, 0.5f); } if(!Register.GetBlockById(chunk.GetBlock(x - 1, y, z)).IsSolid(Direction.WEST)) { meshData = MeshData.CreateFaceWest(chunk, x, y, z, this, meshData, 0.5f); } return meshData; }
/** * Assemble a downwards facing face. **/ public static MeshData CreateFaceDown(Chunk chunk, int x, int y, int z, Block block, MeshData meshData, float size) { meshData.AddVertex(new Vector3(x - size, y - size, z - size)); meshData.AddVertex(new Vector3(x + size, y - size, z - size)); meshData.AddVertex(new Vector3(x + size, y - size, z + size)); meshData.AddVertex(new Vector3(x - size, y - size, z + size)); meshData.AddQuadTriangles(); meshData.uv.AddRange(MeshData.GetFaceUVs(block, Direction.DOWN)); return meshData; }
/** * Generate data for the given Chunk object. **/ public virtual Chunk ChunkGen(Chunk chunk) { chunk.empty = true; for (int x = 0; x < Chunk.chunkSize; x++) { for (int z = 0; z < Chunk.chunkSize; z++) { chunk = GenerateTerrain(chunk, x, z); } } for (int x = -3; x < Chunk.chunkSize + 3; x++) { for (int z = -3; z < Chunk.chunkSize + 3; z++) { //CreateTreeIfValid(x, z, chunk); } } return chunk; }
public override MeshData GetBlockMesh(Chunk chunk, int x, int y, int z, MeshData meshData) { return meshData; }
void SetBlock(Chunk chunk, int blockId, WorldPos pos, bool replaceBlocks = false) { if (Chunk.InRange(pos.x) && Chunk.InRange(pos.y) && Chunk.InRange(pos.z)) { if (replaceBlocks || chunk.GetBlock(pos.x, pos.y, pos.z) == 0) { chunk.SetBlock(pos.x, pos.y, pos.z, blockId); } } }
/** * Creates a new chunk at the given world position. */ public void CreateChunk(WorldPos pos) { Chunk chunk = new Chunk(); chunk.pos = pos; chunk.world = this; chunks.Add(pos, chunk); if(!FileManager.LoadChunk(chunk)) { chunk = terrainGen.ChunkGen(chunk); MakePhysical(chunk); return; } chunk.empty = IsChunkEmpty(chunk); MakePhysical(chunk); }
/** * Create a new GameObject with a ChunkRenderer component * and link it to the given chunk chunk. * Returns false if the chunk is empty. In that case * no visual chunk will be generated. */ bool MakePhysical(Chunk chunk) { if(!chunk.empty) { Vector3 newPos = new Vector3(chunk.pos.x, chunk.pos.y, chunk.pos.z); GameObject newRenderer = Instantiate(chunkPrefab, newPos, Quaternion.Euler(Vector3.zero)) as GameObject; ChunkRenderer renderer = newRenderer.GetComponent<ChunkRenderer>(); renderer.chunk = chunk; chunk.renderer = renderer; newRenderer.name = "Chunk (" + chunk.pos.x + ", " + chunk.pos.y + ", " + chunk.pos.z + ")"; newRenderer.transform.parent = gameObject.transform; return true; } return false; }
/** * Is this chunk empty? (Only contains air.) */ public bool IsChunkEmpty(Chunk chunk) { foreach(byte block in chunk.blocks) { if(block > 0) { return false; } } return true; }