Help me create Minecraft-like terrain

I am trying to make a Minecraft like game. I managed to create a mesh of a cube using vertices and triangles. I am wondering if there was a way to put them in a 16 by 16 grid?

In start I wrote:

for (int z = 0; z<= zSize; z++)
{
    for (int z = 0; z<= zSize; z++)
    {

    }
}

I just want to put this code in it:

void CreateCube ()
{
	Vector3[] vertices = {
		new Vector3 (0, 0, 0),
		new Vector3 (1, 0, 0),
		new Vector3 (1, 1, 0),
		new Vector3 (0, 1, 0),
		new Vector3 (0, 1, 1),
		new Vector3 (1, 1, 1),
		new Vector3 (1, 0, 1),
		new Vector3 (0, 0, 1),
	};

	int[] triangles = {
		0, 2, 1, //face front
		0, 3, 2,
		2, 3, 4, //face top
		2, 4, 5,
		1, 2, 5, //face right
		1, 5, 6,
		0, 7, 4, //face left
		0, 4, 3,
		5, 4, 7, //face back
		5, 7, 6,
		0, 6, 7, //face bottom
		0, 1, 6
	};
			
	Mesh mesh = GetComponent<MeshFilter> ().mesh;
	mesh.Clear ();
	mesh.vertices = vertices;
	mesh.triangles = triangles;
	mesh.Optimize ();
	mesh.RecalculateNormals ();
}

3 Answers

3

There is obviously a way, you could just make the arrays 16x16 times bigger and shift the indices so that the blocks are in a row in the vertex and triangle arrays. That would work but is not optimal when it comes to rendering and especially when it comes to memory consumption. Lets assume the chunk is 16x16x256 blocks. That’s 65536 blocks and if each block has 12 triangles, thats almost million already. One chunk alone will probably not tank your performance but when there’s tens of them, it’s not going to end well. The way this issue is solved on these types of games is by making the mesh out of faces that are next to air blocks. If face is pointing at solid block, it doesnt need to be included because its between blocks and therefore cant be seen (you can think it like this, your camera can only move on air blocks so it only needs to render the sides of the blocks that points to air blocks). The way this can be implememted is bit similiar to cube marching, you just loop through each block on the chunk, if the block is solid check if the neighbour is air block and if so, add that side (which is just two triangles) to the vertices and triangles lists, otherwise do nothing and move to the next neighbour. This shows relatively easy way to implement this in code. Theres obviously a lot to optimize there but that alone is a lot better than the intuitive way of placing a lot of infividual cubes.

Is it possible to do something like: for (int z = 0; z<= zSize; z++) { for (int z = 0; z<= zSize; z++) { Instantiate(cube, new Vector3(x,0,y); } } And then in another script edit the cube so that only the faces that are exposed to air are shown?

Is it possible to do something like:

for (int z = 0; z<= zSize; z++)
{
    for (int z = 0; z<= zSize; z++)
    {
        Instantiate(cube, new Vector3(x,0,y);
    }
}

And then in another script edit the cube so that only the faces that are exposed to air are shown?

Re-creating Minecraft while you don’t know how to create a nested loop… will be a tall order, friend.

If you are still interested, despite steep learning curve, I answered similar question with this code. I made it reasonably simple and as readable as possible and included comments. It should give you some idea how to proceed and turn noise fields into a mesh:

simple minecraft-like terrain generator · GitHub

It’s something like 100 lines of actual code (read to understand) + 1200 lines to define cell geometry data (can be ignored and not read).

Note:

This way of doing this i.e. big hand-written lookup table for geometry is a dead-end as it is too cumbersome to modify. This is why I created different solution another time here:

multi-threaded cube marching where geometry is sourced from a mesh asset template (artist-friendly) · GitHub

(but it’s far much more complicated as it involves multithreading jobs etc.)