- Home /
What to do to make the chunk check other chunks?
I am working on a Minecraft clone and I have done chunk generation.
Chunk.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Chunk : MonoBehaviour
{
Mesh mesh;
public MeshFilter meshFilter;
public static int chunkSize = 16;
public Block.BlockType[,,] blocks;
public bool isUpdate = false;
public static int count;
private void Start()
{
blocks = new Block.BlockType[chunkSize, chunkSize, chunkSize];
for (int x = 0; x < chunkSize; x++)
{
for (int y = 0; y < chunkSize; y++)
{
for (int z = 0; z < chunkSize; z++)
{
blocks[x, y, z] = Block.BlockType.air;
}
}
}
blocks[8, 8, 8] = Block.BlockType.stone;
isUpdate = true;
}
private void Update()
{
if(isUpdate)
{
isUpdate = false;
ChunkUpdate();
}
}
public Block.BlockType GetBlock(int x, int y, int z)
{
return blocks[x, y, z];
}
public void ChunkUpdate()
{
for (int x = 0; x < chunkSize; x++)
{
for (int y = 0; y < chunkSize; y++)
{
for (int z = 0; z < chunkSize; z++)
{
Block.RenderBlock(x, y, z, this);
}
}
}
mesh = new Mesh();
meshFilter.mesh.Clear();
meshFilter.mesh.vertices = Block.vertices.ToArray();
meshFilter.mesh.triangles = Block.triangles.ToArray();
meshFilter.mesh.RecalculateNormals();
count = 0;
}
}
Block.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class Block
{
public enum BlockType
{
air,
stone,
}
public static List<Vector3> vertices = new List<Vector3>();
public static List<int> triangles = new List<int>();
public static void RenderBlock(int x, int y, int z, Chunk chunk)
{
if (chunk.GetBlock(x, y, z) != BlockType.air)
{
if (!isSolid(x, y + 1, z, chunk))
{
vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
AddTriangles();
}
if (!isSolid(x, y - 1, z, chunk))
{
vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
AddTriangles();
}
if (!isSolid(x, y, z + 1, chunk))
{
vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
AddTriangles();
}
if (!isSolid(x, y, z - 1, chunk))
{
vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
AddTriangles();
}
if (!isSolid(x + 1, y, z, chunk))
{
vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
AddTriangles();
}
if (!isSolid(x - 1, y, z, chunk))
{
vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
AddTriangles();
}
}
}
public static void AddTriangles()
{
triangles.Add((Chunk.count * 4) + 0);
triangles.Add((Chunk.count * 4) + 1);
triangles.Add((Chunk.count * 4) + 2);
triangles.Add((Chunk.count * 4) + 0);
triangles.Add((Chunk.count * 4) + 2);
triangles.Add((Chunk.count * 4) + 3);
Chunk.count++;
}
public static bool isSolid(int x, int y, int z, Chunk chunk)
{
if(chunk.GetBlock(x, y, z) == BlockType.air)
{
return false;
}
else
{
return true;
}
}
}
There are two scripts, Block.cs contains information about blocks, and Chunk.cs generates a chunk. Everything works well, but when I generate a block on the border of a chunk, it gives an error. Block.cs also checks adjacent blocks, if the adjacent block is air, then the side of the block is rendered, otherwise it is not, this chunk is optimized in this way. But the block does not check adjacent blocks outside the chunk. This problem made it difficult for me to create a Minecraft clone. I would be grateful if you have the opportunity to help me with this.
Answer by Llama_w_2Ls · Jan 02 at 04:44 PM
I use one function to do this called IsEmptyAt
which determines if a block is of type air, at a position in the chunk. It also checks neighbouring chunks (if they exist) if the block position is out of bounds.
bool IsEmptyAt(Vector3Int neighbourPos, Vector3Int blockPos, Vector2Int chunkPos)
{
// Locate neighbour in chunk
if (!Blocks.OutOfBounds(neighbourPos))
return Blocks[neighbourPos].Type == BlockType.Air;
var chunkOffset = (neighbourPos - blockPos) * World.instance.ChunkSize;
// Block isn't in any chunk (above the sky and below the ground)
if (chunkOffset.y != 0)
return true;
// Neighbour chunk = current chunk + offset
var neighbourChunkPos = chunkPos + new Vector2Int(chunkOffset.x, chunkOffset.z);
// Block doesn't exist
if (!World.instance.Chunks.ContainsKey(neighbourChunkPos))
return true;
var neighbourChunk = World.instance.Chunks[neighbourChunkPos];
var neighbourBlockPos = neighbourPos + new Vector3Int(chunkPos.x, 0, chunkPos.y) - new Vector3Int(neighbourChunkPos.x, 0, neighbourChunkPos.y);
var neighbourBlock = neighbourChunk.Blocks[neighbourBlockPos];
return neighbourBlock.Type == BlockType.Air;
}
The first thing it does is if the block isn't out of the bounds of the chunk (which can be done by checking the position with its dimensions) then just return the type of the block in the chunk. This is a simple array lookup.
Else, it needs to find which chunk the block is actually in, since it is out of bounds. To find the chunk, you need to store all chunks generated in a dictionary in some World class. This can be referenced using a singleton, which I am using.
If the chunk is out of bounds on the y, I return empty, since chunks only extend infinitely on the x and z. Not the y.
Then, the neighbour chunk position is found, and therefore the chunk (from the World dictionary). If the chunk doesn't exist, I return empty.
Finally, I do some math to find the right block, and return its type. Hope that helps.
I have basic chunk generation in my minecraft clone. If you want to see it, I can upload it to a git directory later. @Random1User
Thanks for the answer! I would like to see the source code of your clone
Check out my github repo. I only uploaded the assets folder with the scene. That should be enough, if you copy it into a new unity project. @Random1User
Your answer
Follow this Question
Related Questions
Minecraft block placing/ block building - how to? 2 Answers
Voxel C# source problems. 1 Answer
map generation issues 0 Answers
This script really makes my game lag! 1 Answer
Question about slideScrolling Voxels 0 Answers