Introduction

In Part I we coded a QuadTree structure to distribute our rooms.

This time we will place a room inside each quadtree node and connect them using corridors. Finally, we will use the generated tilemap to instantiate our world GameObjects.

Unity Package

Last time I placed all the code online in independent pages. This time I’d prefer to just upload a Unity Package with all the code & assets, so you have a “build ready” code to test and play with it.

Try to read the code along with this tutorial to fully grasp everything.

Here it is: DOWNLOAD



Just play the “Test” scene inside /Scenes/ and press Space to generate a dungeon.

Let’s do this!

Architecture

Our Unity scene contains a GameObject named “Dungeon” with the DungeonGeneration script attached.

For our FloorTile GameObject I created a simple quad using the CreatePlane script from the Unify Community HERE. It’s already on the Unity Package.

I also added a Player GameObject with the Unity’s 3rd player controller for testing purposes.

Room creation

We start by creating the rooms. Last time we created the QuadTree nodes by taking into account the room minimum size and max size, but we didn’t think much about the walls that surround our room. So, the function we made last time has now to take into account the size of the walls (in tiles).

That’s easy. Next.

Where to create a room? Well, just look for end nodes in our QuadTree, that is, nodes that don’t have children. When we find one, we “dig” an area in our tilemap with a random size taking into account the current quadtree node size and our room parameters.

QuadTree converted to rooms:

Corridors

This step took me longer than expected. I created a recursive function that checks for nodes containing 4 end-nodes. I connect each end-node’s room center with its neighbor’s room center.

If our current quadtree node doesn’t contain 4 end-nodes, intelligently select and connect end-nodes rooms. You should understand that better by looking at the GenerateCorridors function code.

Walls

Now that we have corridors, we need to place the rooms. We loop all tiles and check if the current tile has a neighbor “corridor” tile or “room” tile. If that’s the case, place a wall tile.

Instantiate GameObjects

GameObjects! We will finally be able to see at something 3D. This is easy. Loop all tiles, and instantiate your desired prefab using the tile id and position. For optimization purposes I just loop through each quadtree end-node and check all tiles it contains, grouping the generated GameObjects in chunks.

Optimizations

I told you that I group all GameObjects in separated rooms. Each room is contained in a GameObject with a “Combine Children” script, which combines its children meshes so the engine does less render calls. We also tick the “Static” box on the inspector for GameObjects that will not move, thus enabling Static Batching for walls and floors.

Where to go from here?

For a start, it would be nice to just optimize the code and assets.

One easy optimization would clearly be to reduce the number of triangles on scene. By looping through each cell of our tilemap we could check which faces are “blocked” from view and which faces can really be seen. Knowing this, we could make a new mesh (or meshes) just taking the “seen” triangles.

Right now I’ve shown you how to create your dungeon. From here, you could play with then random values (or add more randomization yourselves) to create different dungeon layouts.

Some more ideas include using each QuadTree zone to change the built room & walls aesthetics; create multiple dungeons with different parameters and join them together; try to make a multiple level layout playing with verticality; make the algorithm place doors on junctions; etc..

Of course, this is only the level creation. From now on you should start to design your player, monster behaviour, AI & pathfinding, and a huge list of features..

Conclusions

I hope you enjoyed this 2 part tutorial. Send your questions & feedback to the “Ask me anything” or my twitter account.

Follow my tumblr or twitter for more gamedev related posts.

Regards,

David León.

Update 1: Reddit user /u/BigFatNathy made a similar tutorial that can be found here: http://helios.hud.ac.uk/u1070589/blog/?p=178