// Use this for initialization void Start() { data = new byte[worldX, worldY, worldZ]; for (int x = 0; x < worldX; x++) { for (int z = 0; z < worldZ; z++) { int stone = PerlinNoise(x, 0, z, 10, 3, 1.2f); stone += PerlinNoise(x, 300, z, 20, 4, 0) + 10; int dirt = PerlinNoise(x, 100, z, 50, 2, 0) + 1; //Added +1 to make sure minimum grass height is 1 for (int y = 0; y < worldY; y++) { if (y <= stone) { data[x, y, z] = 1; } else if (y <= dirt + stone) //Changed this line thanks to a comment { data[x, y, z] = 2; } else { data[x, y, z] = 0; } } } } chunks = new Chunk[Mathf.FloorToInt(worldX / chunkSize), Mathf.FloorToInt(worldY / chunkSize), Mathf.FloorToInt(worldZ / chunkSize)]; int chunkCount = 1; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; newChunk.transform.parent = transform; chunks[x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks[x, y, z].chunkId = chunkCount; chunks[x, y, z].worldGO = gameObject; chunks[x, y, z].chunkSize = chunkSize; chunks[x, y, z].chunkX = x * chunkSize; chunks[x, y, z].chunkY = y * chunkSize; chunks[x, y, z].chunkZ = z * chunkSize; chunkCount++; } } } }
void Start() { data = new byte[worldX, worldY, worldZ]; for (int x = 0; x < worldX; x++) { for (int z = 0; z < worldZ; z++) { int stone = PerlinNoise(x, 0, z, 10, 3, 1.2f); //when this line had a +10 on the end, the tops of the top-most //blocks didn't render. with +1 now they do stone += PerlinNoise(x, 300, z, 20, 4, 0) + 1; int dirt = PerlinNoise(x, 100, z, 50, 2, 0) + 1; //Added +1 to make sure minimum grass height is 1 for (int y = 0; y < worldY; y++) { if (y <= stone) { data [x, y, z] = 1; } else if (y <= dirt + stone) //Changed this line thanks to a comment { data [x, y, z] = 2; } } } } chunks = new Chunk[Mathf.FloorToInt(worldX / chunkSize), Mathf.FloorToInt(worldY / chunkSize), Mathf.FloorToInt(worldZ / chunkSize)]; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { //Create a temporary Gameobject for the new chunk instead of using chunks[x,y,z] GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; //Now instead of using a temporary variable for the script assign it //to chunks[x,y,z] and use it instead of the old \"newChunkScript\" chunks [x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks [x, y, z].worldGO = gameObject; chunks [x, y, z].chunkSize = chunkSize; chunks [x, y, z].chunkX = x * chunkSize; chunks [x, y, z].chunkY = y * chunkSize; chunks [x, y, z].chunkZ = z * chunkSize; } } } }
public Block this[int x, int y, int z] { get { //if (!InBounds(x, y, z)) // Not within world bounds. // return new Block(BlockID.Air); // Determine what chunk holds this block. int chunkX = x / Chunk.SizeX; int chunkY = y / Chunk.SizeY; int chunkZ = z / Chunk.SizeZ; // Check bounds if (chunkX < 0 || chunkX >= Chunks.GetLength(0) || chunkY < 0 || chunkY >= Chunks.GetLength(1) || chunkZ < 0 || chunkZ >= Chunks.GetLength(2)) { return(new Block(BlockID.None)); // Chunk outside of bounds. } Chunk chunk = Chunks[chunkX, chunkY, chunkZ]; // This figures out the coordinate of the block relative to chunk. int levelX = x % Chunk.SizeX; int levelY = y % Chunk.SizeY; int levelZ = z % Chunk.SizeZ; return(chunk[levelX, levelY, levelZ]); } set { if (!InBounds(x, y, z)) // Not within world bounds. { return; } // first calculate which chunk we are talking about: int chunkX = (x / Chunk.SizeX); int chunkY = (y / Chunk.SizeY); int chunkZ = (z / Chunk.SizeZ); // cannot modify chunks that are not within the visible area if (chunkX < 0 || chunkX > Chunks.GetLength(0)) { throw new Exception("Cannot modify world outside visible area"); } if (chunkY < 0 || chunkY > Chunks.GetLength(1)) { throw new Exception("Cannot modify world outside visible area"); } if (chunkZ < 0 || chunkZ > Chunks.GetLength(2)) { throw new Exception("Cannot modify world outside visible area"); } Chunk chunk = Chunks[chunkX, chunkY, chunkZ]; // this figures out the coordinate of the block relative to // chunk origin. int lx = x % Chunk.SizeX; int ly = y % Chunk.SizeY; int lz = z % Chunk.SizeZ; chunk[lx, ly, lz] = value; } }
public void GenerateChunk(int x, int z) { for (int y = 0; y < chunks.GetLength(1); y++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; chunks[x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks[x, y, z].WorldGO = gameObject; chunks[x, y, z].ChunkSize = chunkSize; chunks[x, y, z].ChunkX = x * chunkSize; chunks[x, y, z].ChunkY = y * chunkSize; chunks[x, y, z].ChunkZ = z * chunkSize; } }
public void GenerateChunk(int x, int z) { for (int y = 0; y < chunks.GetLength(1); y++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - .5f, y * chunkSize + .5f, z * chunkSize - .5f), Quaternion.identity); chunks[x, y, z] = newChunk.GetComponent <Chunk>() as Chunk; chunks[x, y, z].WorldGameObj = gameObject; chunks[x, y, z].ChunkSize = chunkSize; chunks[x, y, z].ChunkX = x * chunkSize; chunks[x, y, z].ChunkY = y * chunkSize; chunks[x, y, z].ChunkZ = z * chunkSize; } }
void Start() { data = new byte[worldX, worldY, worldZ]; for (int x = 0; x < worldX; x++) { for (int z = 0; z < worldZ; z++) { int stone = PerlinNoise(x, 0, z, 10, 2, 1.2f); stone += PerlinNoise(x, 300, z, 20, 3, 0) + 8; int dirt = PerlinNoise(x, 200, z, 50, 2, 0) + 1; for (int y = 0; y < worldY; y++) { if (y <= stone) { data[x, y, z] = 1; } else if (y <= dirt + stone) { data[x, y, z] = 2; } else { data[x, y, z] = 0; } } } } chunks = new Chunk[Mathf.FloorToInt(worldX / chunkSize), Mathf.FloorToInt(worldY / chunkSize), Mathf.FloorToInt(worldZ / chunkSize)]; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; chunks[x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks[x, y, z].worldGO = gameObject; chunks[x, y, z].chunkSize = chunkSize; chunks[x, y, z].chunkX = x * chunkSize; chunks[x, y, z].chunkY = y * chunkSize; chunks[x, y, z].chunkZ = z * chunkSize; } } } chunk.SetActive(false); }
// Use this for initialization void Start() { worldData = new byte[worldX, worldY, worldZ]; for (int x = 0; x < worldX; x++) { for (int z = 0; z < worldZ; z++) { int rock = PerlinNoise(x, 0, z, 10f, 3f, 1.2f); rock += PerlinNoise(x, 200, z, 20f, 8f, 0f) + 10; int grass = PerlinNoise(x, 100, z, 50f, 30f, 0f) + 1; for (int y = 0; y < worldY; y++) { if (y <= rock) { worldData[x, y, z] = (byte)TextureType.grass.GetHashCode(); } else if (y <= grass) { worldData[x, y, z] = (byte)TextureType.rock.GetHashCode(); } } } } chunks = new Chunk[Mathf.FloorToInt(worldX / chunkSize), Mathf.FloorToInt(worldY / chunkSize), Mathf.FloorToInt(worldZ / chunkSize)]; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; chunks[x, y, z] = newChunk.GetComponent <Chunk>() as Chunk; chunks[x, y, z].WorldGO = gameObject; chunks[x, y, z].ChunkSize = chunkSize; chunks[x, y, z].ChunkX = x * chunkSize; chunks[x, y, z].ChunkY = y * chunkSize; chunks[x, y, z].ChunkZ = z * chunkSize; } } } }
private void UpdateChunks() { for (int x = 0; x < chunks.GetLength(0); x++) { for (int z = 0; z < chunks.GetLength(2); z++) { float dist = Vector2.Distance(new Vector2(x * World.ChunkSize, z * World.ChunkSize), new Vector2(player.position.x, player.position.z)); if (dist < DistToLoadChunk) { if (chunks[x, 0, z] == null) { GenerateColumn(x, z); } } else if (dist > DistToDestroyChunk) { if (chunks[x, 0, z] != null) { DestroyColumn(x, z); } } } } }
public void GenColumn(int x, int z) { for (int y = 0; y < chunks.GetLength(1); y++) { //Create a temporary Gameobject for the new chunk instead of using chunks[x,y,z] GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, y * chunkSize + 0.5f, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; //Now instead of using a temporary variable for the script assign it //to chunks[x,y,z] and use it instead of the old \"newChunkScript\" chunks[x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks[x, y, z].worldGO = gameObject; chunks[x, y, z].chunkSize = chunkSize; chunks[x, y, z].chunkX = x * chunkSize; chunks[x, y, z].chunkY = y * chunkSize; chunks[x, y, z].chunkZ = z * chunkSize; } }
private void GenColumn(int x, int z) { for (int y = 0; y < chunks.GetLength(1); y++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, 0, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; newChunk.transform.SetParent(this.transform); //Tile t = new Tile(newChunk, updatedTime); chunks[x, y, z] = newChunk.GetComponent <Chunk>() as Chunk; chunks[x, y, z].worldGO = gameObject; chunks[x, y, z].chunkX = x * chunkSize; chunks[x, y, z].chunkY = y * chunkSize; chunks[x, y, z].chunkZ = z * chunkSize; } }
/// <summary> /// Updates all chunks next frame (threaded) /// </summary> public void UpdateAllChunksNextFrame() { if (chunks == null) { GetChunkReferences(); } for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { AddChunkToUpdateList(x, y, z); } } } }
private void GenColumn(int x, int z) { for (int y = 0; y < chunks.GetLength(1); y++) { string name = "Chunk:" + x + "_" + y + "_" + z; //Create a temporary Gameobject for the new chunk instead of using chunks[x,y,z] GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize - 0.5f, 0, z * chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; Tile t = new Tile(newChunk, updatedTime); chunks[x, y, z] = newChunk.GetComponent <Chunk>() as Chunk; chunks[x, y, z].worldGO = gameObject; chunks[x, y, z].chunkX = x * chunkSize; chunks[x, y, z].chunkY = y * chunkSize; chunks[x, y, z].chunkZ = z * chunkSize; } }
// Use this for initialization void Start() { worldData = new byte[xDimension, yDimension, zDimension]; for (int x = 0; x < xDimension; x++) { for (int z = 0; z < zDimension; z++) { int grid = PerlinNoise(x, 0, z, 10f, 3f, 1.2f); grid += PerlinNoise(x, 200, z, 20f, 8f, 0f) + 5; for (int y = 0; y < yDimension; y++) { if (y >= grid) { worldData[x, y, z] = (byte)textureType.air.GetHashCode(); } else if (y <= grid) { worldData[x, y, z] = (byte)textureType.lightGrid.GetHashCode(); } } } } chunks = new Chunk[Mathf.FloorToInt(xDimension / chunkSize), Mathf.FloorToInt(yDimension / chunkSize), Mathf.FloorToInt(zDimension / chunkSize)]; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize, y * chunkSize, z * chunkSize), new Quaternion(0, 0, 0, 0)) as GameObject; chunks[x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks[x, y, z].WorldGO = gameObject; chunks[x, y, z].ChunkSize = chunkSize; chunks[x, y, z].ChunkX = x * chunkSize; chunks[x, y, z].ChunkY = y * chunkSize; chunks[x, y, z].ChunkZ = z * chunkSize; } } } }
public World(int length, int width, int height) { Length = length; Width = width; Height = height; Chunks = new Chunk[Length / Chunk.SizeX, Width / Chunk.SizeY, Height / Chunk.SizeZ]; for (int x = 0; x < Chunks.GetLength(0); x++) { for (int y = 0; y < Chunks.GetLength(1); y++) { for (int z = 0; z < Chunks.GetLength(2); z++) { Chunks[x, y, z] = new Chunk(this, new Vector3(x * Chunk.SizeX, y * Chunk.SizeY, z * Chunk.SizeZ)); //Chunks[x, y, z].UpdateNeeded = true; } } } HexaClassicClient.OnUpdate += Update; HexaClassicClient.OnDraw3D += Draw; }
private void GenerateChunks() { for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { //Create a temporary Gameobject for the new chunk instead of using chunks[x,y,z] GameObject newChunk = Instantiate(chunk, new Vector3(x * Chunk.chunkSize - 0.5f, y * Chunk.chunkSize + 0.5f, z * Chunk.chunkSize - 0.5f), new Quaternion(0, 0, 0, 0)) as GameObject; newChunk.transform.parent = objectGO.transform; chunks [x, y, z] = newChunk.GetComponent("Chunk") as Chunk; chunks [x, y, z].voxels = voxels; chunks [x, y, z].chunkX = x * Chunk.chunkSize; chunks [x, y, z].chunkY = y * Chunk.chunkSize; chunks [x, y, z].chunkZ = z * Chunk.chunkSize; } } } }
// Use this for initialization void Awake() { data = new byte[worldX, worldY, worldZ]; for(int x=0;x<worldX;x++) { for(int z=0;z<worldZ;z++) { int stone = PerlinNoise(x,0,z,10,3,1.2f); stone+= PerlinNoise(x,300,z,20,4,0)+10; int dirt = PerlinNoise(x,100,z,20,2,2f)+1; for(int y=0; y<worldY; y++) { if(y<=stone){ data[x,y,z]=1; } else if(y<=dirt+stone){ data[x,y,z]=2; } } } } chunks = new Chunk[Mathf.FloorToInt (worldX / chunkSize), Mathf.FloorToInt (worldY / chunkSize), Mathf.FloorToInt (worldZ / chunkSize)]; for(int x = 0; x<chunks.GetLength(0); x++) { for(int y = 0; y<chunks.GetLength(1); y++) { for(int z = 0; z<chunks.GetLength(2); z++) { GameObject newChunks = Instantiate(chunk, new Vector3(x*chunkSize-0.5f, y*chunkSize+0.5f, z*chunkSize-0.5f), new Quaternion(0,0,0,0)) as GameObject; chunks[x,y,z] = newChunks.GetComponent("Chunk") as Chunk; chunks[x,y,z].worldGO = gameObject; chunks[x,y,z].chunkSize = chunkSize; chunks[x,y,z].chunkX=x*chunkSize; chunks[x,y,z].chunkY=y*chunkSize; chunks[x,y,z].chunkZ=z*chunkSize; } } } }
// Use this for initialization void Start() { worldData = new byte[worldX, worldY, worldZ]; for (int x = 0; x < worldX; x++) { for (int y = 0; y < worldY; y++) { for (int z = 0; z < worldZ; z++) { if (y <= 8) { worldData[x, y, z] = (byte)TextureType.rock.GetHashCode(); } } } } chunks = new Chunk[Mathf.FloorToInt(worldX / chunkSize), Mathf.FloorToInt(worldY / chunkSize), Mathf.FloorToInt(worldZ / chunkSize)]; for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { GameObject newChunk = Instantiate(chunk, new Vector3(x * chunkSize, y * chunkSize, z * chunkSize), Quaternion.identity); chunks [x, y, z] = newChunk.GetComponent <Chunk> (); chunks [x, y, z].WorldGO = gameObject; chunks [x, y, z].ChunkSize = chunkSize; chunks [x, y, z].ChunkX = x * chunkSize; chunks [x, y, z].ChunkY = y * chunkSize; chunks [x, y, z].ChunkZ = z * chunkSize; } } } }
void CheckData() { if (saver.isFileExists() == true) { Debug.Log("1"); SaveGlobal global = saver.LoadGlobalData(); offsetX = global.offsetX; offsetZ = global.offsetZ; player = Instantiate(playerGO, new Vector3(global.position[0], global.position[1], global.position[2]), Quaternion.identity); modify.playerGO = player; saver.playerGO = player; for (int x = 0; x < chunks.GetLength(0); x++) { for (int z = 0; z < chunks.GetLength(2); z++) { SaveChunk chunk = saver.LoadChunkData(x, z); if (chunk != null) { SaveBytesToData(chunk); SaveChunkToArray(chunk.chunkIdX, chunk.chunkIdZ); } } } } else { Debug.Log("2"); player = Instantiate(playerGO, new Vector3(worldX / 2f, 50f, worldZ / 2f), Quaternion.identity); modify.playerGO = player; saver.playerGO = player; offsetX = Random.Range(0, 999999); offsetZ = Random.Range(0, 999999); } }
public World(int length, int width, int height) { Length = length; Width = width; Height = height; Chunks = new Chunk[Length / Chunk.Size.X, Width / Chunk.Size.Y, Height / Chunk.Size.Z]; for (int x = 0; x < Chunks.GetLength(0); x++) { for (int y = 0; y < Chunks.GetLength(1); y++) { for (int z = 0; z < Chunks.GetLength(2); z++) { Chunks[x, y, z] = new Chunk(this, new Vector3I(x * Chunk.Size.X, y * Chunk.Size.Y, z * Chunk.Size.Z)); //Chunks[x, y, z].CreateMesh(); } } } Spawn = new Vector3I(Length / 2 + 5, Width / 2 + 5, 5); Client.OnUpdate += Update; Client.OnDraw3D += Draw; }
/// <summary> /// Given a world coordinate, tells the chunk holding that coordinate to update. /// Also tells all 4 neighbours to update (as an altered block might exist on the /// edge of a chunk). /// </summary> /// <param name="worldXCoordinate"></param> /// <param name="worldYCoordinate"></param> /// <param name="worldZCoordinate"></param> private void SetChunkContainingBlockToUpdate(int worldXCoordinate, int worldYCoordinate, int worldZCoordinate) { //Updates the chunk containing this block int updateX = Mathf.FloorToInt(worldXCoordinate / ConfigurationManager.Instance.Chunk_Diameter); int updateY = Mathf.FloorToInt(worldYCoordinate / ConfigurationManager.Instance.Chunk_Diameter); int updateZ = Mathf.FloorToInt(worldZCoordinate / ConfigurationManager.Instance.Chunk_Diameter); Chunks[updateX, updateY, updateZ].updateNeeded = true; // Also flag all 6 neighbours for update as well if (updateX - 1 >= 0) { Chunks[updateX - 1, updateY, updateZ].updateNeeded = true; } if (updateX + 1 < Chunks.GetLength(0)) { Chunks[updateX + 1, updateY, updateZ].updateNeeded = true; } if (updateY - 1 >= 0) { Chunks[updateX, updateY - 1, updateZ].updateNeeded = true; } if (updateY + 1 < Chunks.GetLength(1)) { Chunks[updateX, updateY + 1, updateZ].updateNeeded = true; } if (updateZ - 1 >= 0) { Chunks[updateX, updateY, updateZ - 1].updateNeeded = true; } if (updateZ + 1 < Chunks.GetLength(2)) { Chunks[updateX, updateY, updateZ + 1].updateNeeded = true; } }
/// <summary> /// Given a world coordinate, tells the chunk holding that coordinate to update. /// Also tells all 4 neighbours to update (as an altered block might exist on the /// edge of a chunk). /// </summary> /// <param name="worldXCoordinate"></param> /// <param name="worldYCoordinate"></param> /// <param name="worldZCoordinate"></param> private void SetChunkContainingBlockToUpdate(int worldXCoordinate, int worldYCoordinate, int worldZCoordinate) { //Updates the chunk containing this block int updateX = Mathf.FloorToInt(worldXCoordinate / ConfigurationManager.Instance.Chunk_Diameter); int updateY = Mathf.FloorToInt(worldYCoordinate / ConfigurationManager.Instance.Chunk_Diameter); int updateZ = Mathf.FloorToInt(worldZCoordinate / ConfigurationManager.Instance.Chunk_Diameter); Chunks[updateX, updateY, updateZ].updateNeeded = true; // Also flag all 6 neighbours for update as well try { if (updateX - 1 >= 0) { Chunks[updateX - 1, updateY, updateZ].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX-1} {updateY} {updateZ}"); } try { if (updateX + 1 < Chunks.GetLength(0)) { Chunks[updateX + 1, updateY, updateZ].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX + 1} {updateY} {updateZ}"); } try { if (updateY - 1 >= 0) { Chunks[updateX, updateY - 1, updateZ].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX} {updateY - 1} {updateZ}"); } try { if (updateY + 1 < Chunks.GetLength(1)) { Chunks[updateX, updateY + 1, updateZ].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX} {updateY + 1} {updateZ}"); } try { if (updateZ - 1 >= 0) { Chunks[updateX, updateY, updateZ - 1].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX} {updateY} {updateZ - 1}"); } try { if (updateZ + 1 < Chunks.GetLength(2)) { Chunks[updateX, updateY, updateZ + 1].updateNeeded = true; } } catch (IndexOutOfRangeException e) { Debug.Log(e); Debug.Log($"Tried setting chunk {updateX} {updateY} {updateZ + 1}"); } }
private void SetupNeighbors() { int cW = chunks.GetLength(0); int cH = chunks.GetLength(1); int cL = chunks.GetLength(2); // Setup chunk neighbors for (int x = 0; x < cW; x++) { for (int y = 0; y < cH; y++) { for (int z = 0; z < cL; z++) { for (int i = 0; i < 6; i++) { switch (i) { case (int)Face.front: if (z - 1 >= 0) { chunks[x, y, z].neighbors[i] = chunks[x, y, z - 1]; } break; case (int)Face.top: if (y + 1 < cH) { chunks[x, y, z].neighbors[i] = chunks[x, y + 1, z]; } break; case (int)Face.left: if (x - 1 >= 0) { chunks[x, y, z].neighbors[i] = chunks[x - 1, y, z]; } break; case (int)Face.right: if (x + 1 < cW) { chunks[x, y, z].neighbors[i] = chunks[x + 1, y, z]; } break; case (int)Face.bottom: if (y - 1 >= 0) { chunks[x, y, z].neighbors[i] = chunks[x, y - 1, z]; } break; case (int)Face.back: if (z + 1 < cL) { chunks[x, y, z].neighbors[i] = chunks[x, y, z + 1]; } break; } } } } } // Setup block neighbors for (int cx = 0; cx < cW; cx++) { for (int cy = 0; cy < cH; cy++) { for (int cz = 0; cz < cL; cz++) { int bw = chunks[cx, cy, cz].blocks.GetLength(0); int bh = chunks[cx, cy, cz].blocks.GetLength(1); int bl = chunks[cx, cy, cz].blocks.GetLength(2); for (int bx = 0; bx < bw; bx++) { for (int by = 0; by < bh; by++) { for (int bz = 0; bz < bl; bz++) { for (int i = 0; i < 6; i++) { switch (i) { case (int)Face.front: if (bz - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx, by, bz - 1]; } else if (cz - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz - 1].blocks[bx, by, bl - 1]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.front); } break; case (int)Face.top: if (by + 1 < bh) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx, by + 1, bz]; } else if (cy + 1 < cH) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy + 1, cz].blocks[bx, 0, bz]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.top); } break; case (int)Face.left: if (bx - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx - 1, by, bz]; } else if (cx - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx - 1, cy, cz].blocks[bw - 1, by, bz]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.left); } break; case (int)Face.right: if (bx + 1 < bw) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx + 1, by, bz]; } else if (cx + 1 < cW) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx + 1, cy, cz].blocks[0, by, bz]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.right); } break; case (int)Face.bottom: if (by - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx, by - 1, bz]; } else if (cy - 1 >= 0) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy - 1, cz].blocks[bx, bh - 1, bz]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.bottom); } break; case (int)Face.back: if (bz + 1 < bl) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz].blocks[bx, by, bz + 1]; } else if (cz + 1 < cL) { chunks[cx, cy, cz].blocks[bx, by, bz].neighbors[i] = chunks[cx, cy, cz + 1].blocks[bx, by, 0]; } else { chunks[cx, cy, cz].blocks[bx, by, bz].Create(Face.back); } break; } } } } } } } } }
protected virtual void Awake() { allocationQueue = new Queue <Chunk>(); fillQueue = new Queue <Chunk>(); renderQueue = new Queue <Chunk>(); for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { Chunk chunk = new Chunk(x, y, z); chunks[x, y, z] = chunk; allocationQueue.Enqueue(chunk); } } } for (int x = 0; x < chunks.GetLength(0); x++) { for (int y = 0; y < chunks.GetLength(1); y++) { for (int z = 0; z < chunks.GetLength(2); z++) { Chunk chunk = chunks[x, y, z]; // left if (x > 0) { chunk.xMinusChunk = chunks[x - 1, y, z]; } // right if (x < chunks.GetLength(0) - 1) { chunk.xPlusChunk = chunks[x + 1, y, z]; } // bottom if (y > 0) { chunk.yMinusChunk = chunks[x, y - 1, z]; } // top if (y < chunks.GetLength(1) - 1) { chunk.yPlusChunk = chunks[x, y + 1, z]; } // back if (z > 0) { chunk.zMinusChunk = chunks[x, y, z - 1]; } // front if (z < chunks.GetLength(2) - 1) { chunk.zPlusChunk = chunks[x, y, z + 1]; } } } } }
public void PopulateChunks() { GameObject[] chunkArr = GameObject.FindGameObjectsWithTag ("Chunk"); chunks = new Chunk[Mathf.FloorToInt (worldX / chunkSize), Mathf.FloorToInt (worldY / chunkSize), Mathf.FloorToInt (worldZ / chunkSize)]; print ("Found " + chunkArr.GetLength(0) + " chunks."); print ("Placing " + chunks.GetLength(0) + "x" + chunks.GetLength(1) + "x" + chunks.GetLength(2) + " grid of chunks"); foreach (GameObject chunkGO in chunkArr) { Chunk chunk = chunkGO.GetComponent<Chunk>(); int x = chunk.chunkX/chunkSize; int y = chunk.chunkY/chunkSize; int z = chunk.chunkZ/chunkSize; chunkGO.transform.position = new Vector3 (x*chunkSize-0.5f, y*chunkSize+0.5f, z*chunkSize-0.5f ); chunks[x,y,z] = chunk; chunk.GetComponent<Chunk>().enabled = true; print ("Placed \"" + chunkGO.name + "\" in chunks[" + x + "," + y + "," + z + "]."); } }
void Generate() { CleanUp(); _chunks = new Chunk[Mathf.FloorToInt(size / chunkSize), Mathf.FloorToInt(worldHeight / chunkSize), Mathf.FloorToInt(size / chunkSize)]; //первый запуск, строим землю if (!_needToLoad) { _mpd = new MidpointDisplacement(size, roughFactor, 0, worldHeight, worldHeight*0.8f); _mpd.SetBaseValue(); _mpd.SetRandomValue(); _mpd.Generate(roughValues); _worldData = new float[size, worldHeight, size]; //generate all world data for (int i = 0; i < size*size; i++) { float height = Mathf.Min(_mpd.data[(int) i/size, i%size], worldHeight - 1); for (int h = 0; h < (int) (height); h++) _worldData[(int) i/size, h, i%size] = 1; if (smooth) { if (height >= 0) _worldData[(int) i/size, (int) (height), i%size] = height - (int) height; } } //разбивает worldData на чанки for (var i = 0; i < _chunks.GetLength(0); i++) { for (var j = 0; j < _chunks.GetLength(1); j++) { for (var k = 0; k < _chunks.GetLength(2); k++) { float chunkX = (i * chunkSize); float chunkY = (j * chunkSize); float chunkZ = (k * chunkSize); _chunks[i, j, k] = CreateChunk(chunkX, chunkY, chunkZ); Block[, ,] chunkData = WorldToBlocks((int)chunkX, (int)chunkY, (int)chunkZ); _chunks[i, j, k].Initialize(chunkData, chunkSize, chunkMaterial, this); } } } } else { var terrain = GameSaver.Instance.LoadTerrain(); var chunksSaveData = Helper.SingleToMulti(terrain.Chunk_0, terrain.Chunk_1, terrain.Chunk_2, terrain.Chunks); for (var i = 0; i < _chunks.GetLength(0); i++) { for (var j = 0; j < _chunks.GetLength(1); j++) { for (var k = 0; k < _chunks.GetLength(2); k++) { var saveData = chunksSaveData[i, j, k]; _chunks[i, j, k] = CreateChunk(saveData.Position.x, saveData.Position.y, saveData.Position.z); _chunks[i, j, k].Initialize(saveData, chunkSize, chunkMaterial, this); } } } terrain = null; chunksSaveData = null; _needToLoad = false; } RegenerateAllChunks(); }
// get the block at position (wx,wy,wz) where these are the world coordinates (not adjusted for shifts or anything) public Block this[int wx, int wy, int wz] { get { // first calculate which chunk we are talking about: int cx = (wx >> Chunk.chunkLogSize) - c0x; int cy = (wy >> Chunk.chunkLogSize) - c0y; int cz = (wz >> Chunk.chunkLogSize) - c0z; // request can be out of range, then return a special // Unknown block type if (cx < 0 || cx > chunks.GetLength(0)) { return(new NullBlock()); } if (cy < 0 || cy > chunks.GetLength(1)) { return(new NullBlock()); } if (cz < 0 || cz > chunks.GetLength(2)) { return(new NullBlock()); } Chunk chunk = chunks[cx, cy, cz]; // this figures out the coordinate of the block relative to // chunk origin. int lx = wx & Chunk.chunkMask; int ly = wy & Chunk.chunkMask; int lz = wz & Chunk.chunkMask; return(chunk[lx, ly, lz]); } set { // first calculate which chunk we are talking about: int cx = (wx >> Chunk.chunkLogSize) - c0x; int cy = (wy >> Chunk.chunkLogSize) - c0y; int cz = (wz >> Chunk.chunkLogSize) - c0z; // cannot modify chunks that are not within the visible area if (cx < 0 || cx > chunks.GetLength(0)) { throw new Exception("Cannot modify world outside visible area"); } if (cy < 0 || cy > chunks.GetLength(1)) { throw new Exception("Cannot modify world outside visible area"); } if (cz < 0 || cz > chunks.GetLength(2)) { throw new Exception("Cannot modify world outside visible area"); } Chunk chunk = chunks[cx, cy, cz]; // this figures out the coordinate of the block relative to // chunk origin. int lx = wx & Chunk.chunkMask; int ly = wy & Chunk.chunkMask; int lz = wz & Chunk.chunkMask; chunk[lx, ly, lz] = value; } }