Voxel Engine Part1 – Let’s display some cubes!

Hey, First Post! Yesterday I decided to start a new project with Unity3D Free. Why Unity3D ? Because it’s easy to work with and I like C#.  It also deals with a lot of things that aren’t really nice to do on your own.

I’ve been thinking for a while about implementing some Procedural Generation algorithms. The algorithm used in this video, Marching Cube, is something I would eventually like to try. However, I figured I’d try with something simpler to get my head around the concepts. Since I’ve been playing Minecraft a lot recently, I figured that making a Voxel Engine would be an interesting project that would allow me to learn a lot.

This 3 part tutorial will explain the path I took to achieve the result shown in this picture :

Result of the Minecraft-Clone prototype

Fig1 – Example of the procedurally generated cube world

The example above is a 125x125x15 chunk.It contains a total of 91803 cubes, if we count the occluded ones. So how did I get there ? Let’s start from the basics!

First of all, here are some links :

Up-To-Date WebPlayer (Small world for quick calculation, 25x12x25)

Up-To-Date Unity Project on GitHub (Will be updated as the project goes on)

Part3 Unity Project on GitHub (Will stay as the project end at Part3.)

Game Plan

So, without any experience on the topic, what would be the path to have a bunch of nicely organized cube displayed on the screen ? Here is the path I took :

  1. Setup a basic environment
  2. Create and texture a cube
  3. Display a bunch of cube
  4. Create a 3D array containing the information of all cube
  5. Fill the 3D array and display it
  6. Use a Perlin Noise algorithm generate a coherent random world

In this post, I will assume that the user know its way around unity. I’ll try to explain as much as possible so beginner can follow but I won’t explain how Unity works, that’ll be for another post!

Also, I’m not claiming in anyway that it is the good way to do it. I’ll go as far as saying that it is probably not the best way to do it. This is a naive implementation that will definitely end up using too many GameObject. However, this will be a nice and easy way to tackle the problem. We will look afterward on ways to improve the engine.

The objective here is to learn. I really like to try things myself and look after how it has been done by others. This way, I understand much more the design decisions and the code I’m looking at.

1.Setup a basic environment

I didn’t want to spend too much time on this part so I kept it simple.

I started by creating a new scene and by loading the First Person Controller provided by unity. It isn’t perfect, but it will do for a quick prototype. I changed the Extra Height parameter in the Character Motor script/Jumping to 50. This allow for an easier navigation in the height of the world. I’ll remake the Character Controller in a later post.

It’s position is 0x2x-10 to be able to see created cube. (Assets -> Import Package -> Character Controller).

Then, I created a simple 1000x1x1000 cube to make the ground at position 0 x 0 x-1. (GameObject -> Create Other -> Cube)

Then I added a Directional Light to light the see a bit! (GameObject -> Create Other -> Directional Light)

I finally created an empty GameObject called __GameMaster to handle everything related to cube generation. I always put “__” in front of GameObjects that are only script handler and not part of the actual scene. (GameObject -> Create Empty)

2.Display 1 cube

Now that the basic scene is there, we can try to display our first cube. First thing to do is to create a script responsible for the generation of cube. Mine is called CubeGeneration. Original, I know.

(In the Project window, Right-Click -> Create -> C# Script)

Now attach this new script to the “__GameMaster” GameObject.

(edit : Sorry for bad code formatting, I’ll figure a way to keep code formatting when posting it)

In CubeGeneration.cs, Add the following code :


using UnityEngine;
 using System.Collections;

public class CubeGeneration : MonoBehaviour {
public GameObject Cube;

// Use this for initialization
void Start ()
{
CreateCube(0,0,0);
}

void CreateCube(int _posX, int _posY, int _posZ)
{
GameObject.Instantiate(Cube, new Vector3(_posX, _posY, _posZ), Quaternion.identity);
}

Now all we need is to create a Cube and save it as a prefab so it can easily be instantiated. This line :


public GameObject Cube;

means that the script inspector will need to be given a prefab so the script know which prefab to instantiate. So let’s create a prefab and add a material to it!

To do this, Create a Cube, drag it from the Hierarchy window to the Project window. The cube is now a prefab that you can copy over and over. Now we need to add texture to it. I took my textures from the Standard Terrain Assets :

(Assets -> Import Package -> Terrain Assets).

To apply the texture to the cube, you need to create a material first.

(Project Window Right-Click -> Create -> Material)

Now drag and drop the texture from Terrain Assets onto the Material texture slot. I created 3 different Material for 3 different block :

  • Grass
  • Rock
  • Sand

I then copied the cube Prefab twice to have 3 different Prefab. I applied the material to the 3 cube prefab to have 3 different blocks :

  • CubeGrass
  • CubeRock
  • CubeSand

Finally, I drag and drop one of the prefab onto the __GameMaster’s CubeGeneration Script Inspector. Your Unity UI should look like this :

2 - Cube UI

Fig2 – Unity’s UI after cube texturing

When you hit Play, you should get a nice textured cube in front of you!

4 - 1CubeResult

Fig3 – Unity Scene with script running.

If you don’t get the cube, you probably forgot to attach the CubeGeneration.cs to the __GameMaster or you forgot to add the cube’s prefab to the CubeGeneration.cs script.

3.Display a bunch of cube

We now have a cube on screen, yea! Next step would be to draw a bunch of cube on screen. For test purpose, let’s make a prism of sizeX x sizeY x sizeZ and fill it with random blocktype. Here is the updated CubeGeneration.cs script :


using UnityEngine;
using System.Collections;

public class CubeGeneration : MonoBehaviour {

public GameObject CubeGrass;
public GameObject CubeRock;
public GameObject CubeSand;
// Use this for initialization
void Start ()
{
    CreatePrism(10,7,3);
}

// Create a sizeX by sizeY by sizeZ prism with random cube in it
  void CreatePrism(int sizeX, int sizeY, int sizeZ)
  {
    int _curType; // The blocktype of the next created cube

    for(int i = 0; i < sizeX; i++)
    {
      for(int j = 0; j < sizeY; j++)
      {
        for(int k = 0; k < sizeZ; k++)
        {
          _curType = Random.Range (1,4); // The last number is excluded, this will return a random number between 1,2 and 3
          CreateCube (i,j,k, _curType); // Call the CreateCube function to instantiate a cube
        }
      }
    }
  }

  // Create a Cube at the inputted position with a texture matching the blockType
  void CreateCube(int _posX, int _posY, int _posZ, int _blockType)
  {
    GameObject _CurCube = CubeRock; //Local variable that only remember the good prefab to be displayed

    // _blockType is inputted as an integer. 1 = Grass, 2 = Rock, 3 = Sand
    if(_blockType == 1)
      _CurCube = CubeGrass;
    else if(_blockType == 2)
      _CurCube = CubeRock;
    else if(_blockType == 3)
      _CurCube = CubeSand;

    // Instantiate a new cube at the inputted position, facing identity
    GameObject.Instantiate(_CurCube, new Vector3(_posX, _posY, _posZ), Quaternion.identity);
   }
 }

Don’t forget to drag and drop the 3 cube prefab to the CubeGeneration Inspector or you will have problems. You should get something similar to this :

5 - PrismResult

Pretty cool! We now have a bunch of cube on the screen!  It’s now time to keep track of which cube is where and have a better data structure. This is exactly what Part 2 will do with the implementation of a Perlin Noise algorithm!

Feel free to ask question in the comment section if you run into trouble trying to implement this. I’m also interested in getting feedback on the structures of the tutorials and on what you would like me to try to implement in later posts!

See you in Part2!

Advertisements

5 thoughts on “Voxel Engine Part1 – Let’s display some cubes!

  1. Pingback: Minecraft-Clone – Part 2 | LearningGeek Blog

  2. Pingback: Chess Part1 – Board and basic movement | LearningGeek Blog

  3. lovely tuts! i just picked up unity coming from NeoAxis and im loving it. got me going on creating a planet from cubes. its a learning experience so optimization will come. later.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s