[Unity] Voxel terrain generation - 1 - Making a cube

in voxel •  6 years ago  (edited)

In this first chapter, we will create the new project and generate our first cube.

The cube generation in Unity can be a bit hard for some developers, there are a lot of things to keep in mind. But there are many ways to improve and make it easy.

What is a cube?

Here the cube, in Unity, is called a "Mesh" composed of 6 "Quads", which are all faces. It is a type of object which contains multiple values for the shape : Vertices, Triangles and UVs.

 - Vertices : Summits, or corners of the quad. (0,1,2 and 3) . Each one has it's own coordinate in the world.

 -----------------------

- Triangles : Because a square is 2 triangles (Blue and Green zones)

Meshes in Unity work with triangles only, that's why we need triangles to make a quad.

Also, to make a triangle, we use 3 vertices, here 0,1,2 and 0,2,3. We store them in an array or a list.

Example :

Triangle array = {0,1,2,0,2,3}

Unity will automatically slice the array to have 3 int (0,1,2,  0,2,3). We stored both of the triangles and we have the square.

 Remember that 0,1,2 is different than 2,1,0. The order will tell Unity which side of the square will be rendered because a quad is visible from one side only 

 -----------------------

- UVs : 


UVs are the coordinates of each corner of the texture. It tells the quad how to apply the image.

Usually, their order is

1,1 (Top right),

0,1 (Top left),

0,0 (Down left),

1,0 (Down right).

 
The full texture will we applied to the quad. It will look like this. 

 

But we can also change the size of the texture applied to the quad by changing the coordinate values.

Here we have (In order) :

0, 0.5 (Top middle),

0, 1 (Top left),

0, 0.5 (Left middle),

0.5, 0.5 (Center).


Those values will be given in an array and Unity will look in it to get the order and the coordinates. That's how they are defined to the quad. 

 -----------------------

There are also other values we can use in a mesh : 

 - Normals : 

 

They give the direction of a quad, which way it is facing, so Unity knows how to render the face. 

Normals are placed on vertices and are usually given with "Vector3.direction".

They can also be calculated automatically by Unity to avoid adding normals to the code, it is better in a cube. But in a more complex generated mesh, you may want to give them manually.


 Now that we have everything we need, we can make the cube. 

- First, you will need a new project in Unity.

- Let's create a new C# script called "Cube".

- Create an empty object called "Cube Generator" but don't add the script yet.


 We need two lines above "public class Cube". 

 - Now you can add the script to the object. Unity will read the script and see that the object requires two components to work. It will add them automatically. 

 - You can remove the Update method, it won't be used. 


 

We create 3 lists to store the values of the mesh. 

Vertices are positions in the world, meaning that they are Vector3.

Triangles are Integers.

UVs are Vector2, they are coordinates in the texture, which is a 2D plane.

Using a list instead of an array is a way to store every value of the cube easily instead of merging every quad array into a single one.

We also create the mesh of the cube, the final mesh that will contain our generated values.

 Now we can generate it : 

 

In the Start method, we call another method,  "GenerateCube". It will take care of the cube generation. There, you can compare if there is another cube in front of a side or change mesh properties before making the cube.

It starts with "CubeMesh = new Mesh()", which creates an empty mesh to work with and to store our values.

Then, for each side of the cube, it will call the method "CreateCubeSide" and give the name of which side it wants to be created.

--- 

In "CreateCubeSide", we ask for a side. Then, we use a switch, it's like a list of possibilities.

So, in the case the variable "side" is equals to "front", we do what is between "case "front"" and "break". Notice that "break" is the end of the case and the switch will stop after it is reached.

Every possibility will be between "case possibility :" and "break". It's like and easy a small version of conditions with a lot of "else if".


Now, let's talk about vertices.

We have to give every vertex possible in the cube. Here is the list of them.

 Notice that we start from the center of the cube and follow the axis. We add 0.5 or subtract 0.5 to each direction.  


 

We add every vertex possible to the code as Vector3 before using them for a side of the cube. So only the needed vertices will be used and you won't have to make new ones for each side.

Finally, for the front side, we set which vertices will be used, just like the picture above. The order is important, just like triangles.


 But now, we need to set the triangles. There is just a bit more to understand but it's not that hard. 

 

Before creating the vertices, we will set the triangles order. Like i said, this gives to the quad the order to draw both of the triangles. And in which way the side is visible.

We add the new triangles to the list.

(3 + 3 integers)

So we set the order 0,1,2 and 0,2,3, but we add the number of vertices already existing, it tells Unity that we are at the end of the list and we are adding new vertices, so it must use the last values that will be given.

We must add the triangles before the vertices because it will use the vertices number, and we need to add the first triangles (index 0 in the list) before there are vertices



Now, the cube exists in the memory, not physically.

But we have to make a physical cube!

And to do that, we will make a new method called "GeneratePhysicalCube", nothing more, nothing less.

Then we can call it after generating all the faces, inside "GenerateCube".

 We will put our new values inside the new cube mesh and the new cube mesh inside the object. 

 

First, we keep the MeshFilter component of the object in a variable, to make it easier to access and use. 

Then, we put the values we created in the empty cube mesh. We give them as arrays instead of lists, because the mesh only accepts arrays.

We use RecalculateBounds and RecalculateNormals to let Unity recalculate the quads directions and properties. 

Finally, we put the cube mesh in the object's MeshFilter. (Remember that the meshfilter is used to give a shape to the object, and the mesh renderer makes it visible). 


Now if you test your game, you should see the front of the cube drawn in the scene. 

(Notice that the quad is made of two triangles)


The next thing to do is generate the other faces

And don't forget to call them in the "GenerateCube" method!

 

Now the cube is ready, the last thing to do is add a texture to it :

For now, we will use only one texture, there is no need to have more than one.

To do that, you will need a texture in your project folder, you can use anything you want.

If you drag your texture to the cube, it will give a color, not an image. That's because one pixel of the texture is scaled to the cube size.

To fix that, we will add UVs to the cube.

And there are only two things to do :

 - Set the uv order to the new quad that will be created : 

 - Add those values to the final mesh : 

 And now you have the final cube

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!