Richard Hawkes is a youtuber, who provides tutorials on both Unity development and blender model creations. He has created a Unity Dungeon Creation tutorial series, the maze he has implemented and demonstrated creates a Random Maze upon being played.
Using this tutorial I was able to create the most perfect dungeon maze for the VR demo, I plan on implementing for my project. I will be making some changes to the maze to make it more immersive for VR though, using the Steam VR plugin I will be able to turn it into a VR game. I’m also hoping I can create and AI that can traverse the dungeon using path-finding.
To explain this process, I will give an overview of what was done, then I will talk about the assets created to be used and the scripts involved.
The purpose of the tutorials was to create a maze that would be random every time it was played. With that in mind, the first part of the tutorial was creating a prototype maze using the console in unity to display the maze that would be created.
Think of this as the blue print of the end project.
The second part of the tutorial was about visualizing the maze by creating the assets that would be used to replicate each shape or character, not specific enough, above is the blueprint, well the characters used to make that blueprint happen were these “─│┌ ┐└ ┘├ ┤┬ ┴ ┼ “. These characters made up the map above, so creating the 3D shapes for each was what came next to visualize the 3D version of the map. These shapes were simply made in Unity using cubes arranged in different positions, then saved as prefabs.
A dungeon display script was added, which would display the blueprint map in unity. Example:
Third tutorial involved learning about “Recursion”, the reason for learning about recursion is because every now and then in the prototype version of the maze their would be ‘islands’, parts of the maze that were not connected, so in order to get rid of them, recursion was introduced.
Recursion is in a simple view, is when you have a function that calls itself, normally that would mean that it would be stuck in an infinite loop, so controls are needed to make sure it doesn’t always call itself. Example of this was creating a factorial, which is a number itself times every number underneath it (4 x 3 = 12 x 2 = 24 x 1 = 24). Using the recursion method, a function was created that would traverse though each row and cell of the maze map and if their was a blank space between one piece and another, that would create an island, the shapes used to create the maze would not be instantiated, thus not created.
Fourth tutorial was adding a room to the dungeon, so it wasn’t just an endless maze of tunnels. The room was also created to randomly generate like the maze, so it wouldn’t always be in the same place.
Fifth tutorial, was modeling the dungeon tunnels, so that the player can move around inside, this was done using blender, I did not do this part of the tutorial because I have no knowledge of how to use blender, so I simply downloaded the tunnel assets.
Next was adding the tunnels into the maze, which was pretty much exactly the same as using the first shapes, basically just replacing them.
The seventh tutorial was adding the chamber or room into the maze, it did have a basic shape in place when it was first added, but now it has been given a hollowed out space. The chamber is made up of multiple prefab shapes, that join together to make the chamber, the chamber has two entrances, well only two seem to generate, but they can generate on 4 sides. If you look at the blue print maze map, you will see a area that has double lined characters with @ symbols inside, this represents the chamber area.
This is what the maze looks like at this point of the tutorial.
Eighth tutorial was about getting rid of the dead ends you can see on the maze, this was done by adding a new shape to fit on the ends of the ends. We needed to make a shape to fit with dead ends facing, left, right, down and up. The dead ends use to be represented by “0’s”, but were replaced with solid colored arrows, if you look back at the blueprint map of the maze, you will see those arrows, and they represent where the dead ends are.
The final part of the tutorial was texturing the the tunnels to look more like a dungeon. Using a gravel almost looking texture, added to the tunnel objects, the dungeon was now complete. Using the Steam VR asset provided by Valve, turning the dungeon generator into a VR game was possible, the texturing of the dungeon, really brings the feeling of immersion games require.
This section I will just talk about the objects created to make the dungeon and some assets that were used for the testing.
Each shape was fitted with box colliders for every side they have, walls, roof and ground, this was to stop the player form falling through the dungeon or running out of the wall. I have noticed that sometimes in the corner pieces it is hard to traverse through if you go to close to the side for a sharp turn.
Standard assets, is a package unity provide free to it’s users, it has a set of models, objects and player controls that the user can use to create their games, in my case I use them as a way to test the environment or basic game play before implementing the VR components. For this tutorial, using the first person player prefab to traverse through the environment, to make sure their were no holes the player could fall through.
The chamber pieces were created using Blender, Blender is a free open source 3D creation application. The two screen shots provided below are the two pieces that make up the chamber, each of the chamber prefabs have the Dungeon Character Mapping script, which is how we map where the pieces will appear in the generator. The pieces that make up the whole chamber include, 4 corners, 4 walls, 4 possible entrances and the room piece, which is placed in the middle, these prefab objects make up the chamber.
The tunnels objects make up the rest of the dungeon. Each piece is mapped to specific character which is where they are placed in the dungeon when it generates, the mapping is done in a MapGenerator script and the placement is decided by this script and the displaydungeon script. The objects were also created in Blender.
This section, I think I will discuss the scripts by going through each of the functions of the specific script. It will be easier to explain how the scripts work by just doing an individual function, than to try explain it in one massive paragraph.
This is just an example script, was mainly to grasp the concept of Recursion before the actual implementation of it into the main scripts. Earlier in this blog, I talked about Recursion and an example for it, this is that example in code.
Here is the output of the recursion code.
Map Generator Script
This script is the core of the dungeon generator, it does all the heavy lifting. Code is commented, but I think I will re-explain for myself.
These are the parameters used through out the scripts. Using public for the mapRows and Columns allows us to change the size of the map in unity, instead of having to change it in the code.
Char represents a character as a UTF-16 code unit. The reason we are using char is because some of the characters used for the mapping of the objects are UTF characters, and this was the only way to make them valid in the script.
boxCharacters is a part of a function later down the line of this script, which is the InitializeBoxCharacters funtion, when the script is running the box character in unity is filled with the characters we are validating. The arrays underneath are for the the same function as we have a list of different outcomes.
In the parameters, I had some string arrays made up, and their purpose comes into play in this functions. Basically what this function does is, initialize the characters being used and initializes a list of all the possible characters that can link up together, when we output the map.
This function is called on awake, so as soon as the script is run.
Display map outputs the map creation result to the console, it is called in another script.
This function is basically the creation of the map itself. Edited for section explanations.
Yellow Square = This part of the function takes in the amount of rows and columns and creates the border and inserts the free cells. The comments say something about inserting the X’s, the X’s represent the edges of the map where shapes cannot go into or past, the O’s represent the free cells that the shapes can fit into.
Red Square = This is a Random seed generator, this makes the map not generate the same map over and over again.
Blue Square = Calling a function.
Green Square = This is a for loop that fills in the free cells with the shapes, starting at row one and column one it will go through and fill in each cell, if the maps row and column equal one of those characters it is referring to, then that’s fine, continue on, at the end it is getting it calls the function GetValidCharacters which gets every possible valid character than we have initialized and randomly inserting them.
Purple Square = Calling another function
As you can probably tell, this function sorts out the dead ends of the maze, their were sections that had O’s instead of a one of the specified characters which lead to ends that would take you out of the dungeon. This function goes through the map and finds those dead ends and replaces them with hard colored arrows which specify what object will go there.
This function creates the chamber room in the dungeon, it randomly positions the room into the map, using the specified characters as the reference to the objects in unity.
This function is called in InitializeMap to get all valid characters, this is also the recursion function. I commented this piece enough for it not need a proper explanation.
This function is actually called in DungeonDisplay script. What it does is go through each row and column and checks to see if it has visited the cell, if it has visited that cell it will be marked as true. The switch statement goes through the cases of each shape, and checks if there is something there.
Dungeon Display Script
This script takes in functions from the mapGenerator and it creates the visualization part of the dungeon. Takes all the shapes and puts them into their correct places.
The public list is what holds the shapes in unity, where they are being assigned, and we know each shape have the Dungeon Character Mapping script, which just hold their UTF character. The others are pretty self explanatory.
These functions are called upon starting of the generator.
This function loads each of the game object shapes character that has been assigned to them. This function is then called in Start, because it is required straight away.
This functions main purpose is to generate the dungeon, using the MapGenerator functions, this is where we initialize the map using the InitializeMap function and where we use the traverseMap function to get the visited cells, and we also get how many cells have been visited by having it logged to the unity console.
This function goes through and gets the rows and columns like a lot of the others, gets the character in that row and column, checks to see if we have that character, if it exist or if it hasn’t been visited with the help of visitedCells, if their is a character and the cell has been visited then this function will go and return the game object instance and instantiate it into the correct position.
This function goes and returns how many cells have been visited.
Dungeon Character Mapping Script
This script literally has one line of code, which is just enabling us to use UTF characters. This script is attached to every shape, where we then put in it’s specified character that represents it. This script is then called into DungeonDisplay to retrieve each shapes character and insert it into the dungeon.
This tutorial was super! Richard is incredible, this tutorial was exactly what I needed to create my environment for the demo. The explaining of what each piece of code does, I think has increased some of my knowledge into C#, also having to research what specific things do, just so I could understand myself, learning about recursion was an interesting concept. Also, the amount of “for loops” used in pretty much every piece of code has been drilled into me.
A lot of small things I was able to learn about just from going through this series was a good experience. It will be interesting to see how my path finding algorithm will work inside this dungeon once I finish it. Incorporating it into the VR demo, will be fun to experience.
All credit to: