{"id":77290,"date":"2018-02-17T00:21:52","date_gmt":"2018-02-17T00:21:52","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=77290"},"modified":"2021-07-29T19:46:47","modified_gmt":"2021-07-29T19:46:47","slug":"procedural-generation-unity-c","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/procedural-generation-unity-c\/","title":{"rendered":"Procedural Generation with Unity and C#"},"content":{"rendered":"<h4>The series so far:<\/h4>\n<ol>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/introduction-game-development-unity-c\/\">Introduction to Game Development with Unity and C#<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/using-c-functions-animations\/\">Using C# Functions in Your Animations<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/procedural-generation-unity-c\/\">Procedural Generation with Unity and C#<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/pathfinding-unity-c\/\">Pathfinding with Unity and C#<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/extending-unity-editor-c\/\">Extending the Unity Editor with C#<\/a><\/li>\n<li><a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/c-programming\/using-unity-ui-and-c-to-create-a-tic-tac-toe-game\/\">Using Unity UI and C# to Create a Tic-Tac-Toe Game<\/a><\/li>\n<\/ol>\n\n<p>The practice of using procedural generation in games to create an infinite number of maps for the player to explore dates back all the way to the 1970s with games like Akalabeth: World of Doom and Rogue. It&#8217;s still in use today, serving as a major aspect in newer games like Minecraft and Darkest Dungeon. Developers have often used procedural generation to offer infinite gameplay to a potential player, citing that the game is often never going to be the same from one play session to the next. As you can imagine, building such a system can be quite complex to develop.<\/p>\n<p>Procedural generation is defined as a method of creating data via an algorithm instead of manually creating it. You are essentially giving the computer a set of rules to create a level with. These rules can consist of many items, such as how large a level is, how many of a certain object can be created in a level, and so on. Creating a game like this has many benefits beyond simply offering the player infinite replay value for their game. If you&#8217;re making a game with several levels, procedural generation can help you save time and even money. You can also use procedural generation to mix and match various gameplay styles in a way that asks the player to play the game in a unique way every time, further adding to the infinite replay value.<\/p>\n<p>You do have to be careful with procedural generation though, as you can accidentally let the computer build a room with no way to exit, or drop too many enemies into a given space. The possibilities for something bad to happen are almost as infinite as the possible map layouts you can make using this technique. Today you&#8217;ll learn how to make a basic procedural map generation system that makes a few rules to avoid some of these pitfalls. There will be specifications given to the computer as to how these levels should be built, such as where to place an exit, how big to make the starting area, and more. It should be noted that the system made here shouldn&#8217;t necessarily be used for a complete game, but it can help you begin work on your own procedural map generation system.<\/p>\n<h2>Setting up the Unity Project<\/h2>\n<p>First you need to create a new project to work in. Open Unity and in the top right corner select <em>New <\/em>like in Figure 1.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"151\" class=\"wp-image-77291\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image.jpeg\" \/> Figure 1: Creating a new project<\/p>\n<p>Call the project <em>Procedurally Generated Map <\/em>and make sure that it&#8217;s a 3D project. Finish creating the project by specifying its file path and clicking <em>Create project <\/em>near the bottom. Figure 2 shows what the project set up screen should look like before clicking <em>Create project<\/em>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1002\" height=\"573\" class=\"wp-image-77292\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-1.jpeg\" \/> Figure 2: Project setup<\/p>\n<p>Once Unity has finished creating the project your screen should look like the one seen in Figure 3. If you don\u2019t see screens similar to this, select <em>Window &#8211;&gt; Layouts &#8211;&gt; Default<\/em> from the menu.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1521\" height=\"792\" class=\"wp-image-77293\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-2.jpeg\" \/> Figure 3: New 3D Unity project<\/p>\n<p>Before you begin making any objects or code, you&#8217;ll want to make two folders in the <em>Assets<\/em> window near the bottom. Go to the <em>Assets<\/em> window shown in Figure 4 and right click to open a menu. Go to <em>Create <\/em>and then select <em>Folder<\/em>.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"711\" height=\"403\" class=\"wp-image-77294\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-12.png\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 4: Creating a folder in the <em>Assets <\/em>window<\/p>\n<p>Name this first folder <em>Tile Objects. <\/em>Create a second folder and name it <em>Materials<\/em>. These two folders will be used to help organize the tile objects and the materials we&#8217;ll be using on these objects. Figure 5 shows what your <em>Assets<\/em> window should look like when finished.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"450\" height=\"196\" class=\"wp-image-77295\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-3.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 5: Your new assets folder<\/p>\n<p>Now it&#8217;s time to create some objects in your project. Start by going to the <em>Hierarchy <\/em>window and clicking the <em>Create <\/em>button. Hover your mouse over <em>3D Object <\/em>and then choose <em>Cube<\/em> to create a cube in the world. Figure 6 shows how to create the cube object.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"353\" height=\"146\" class=\"wp-image-77296\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-13.png\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 6: Creating a new cube object.<\/p>\n<p>Using the <em>Transform <\/em>component in the <em>Inspector <\/em>window to the right, set the <em>Y <\/em>value under <em>Scale <\/em>to 0.1 as shown in Figure 7.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"567\" height=\"172\" class=\"wp-image-77297\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-4.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 7: Setting the <em>Y Scale<\/em> of the cube object.<\/p>\n<p>Rename the object <em>WhiteTile<\/em> by using the name field near the top of the <em>Inspector <\/em>window as shown in Figure 8.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"567\" height=\"172\" class=\"wp-image-77298\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-5.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 8: Renaming the object.<\/p>\n<p>With the <em>WhiteTile <\/em>object selected, press Ctrl + D four times to duplicate the object. You should now have five <em>WhiteTile<\/em> objects in your <em>Hierarchy<\/em> window like in Figure 9.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"302\" height=\"257\" class=\"wp-image-77299\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-6.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 9: Your new <em>Hierarchy <\/em>window.<\/p>\n<p>It&#8217;s time to take a break from these tiles and move on to creating materials. Materials are items used in games that give an object its appearance. Examples of materials in games include the bark on trees or wood on a table, though those examples have a little more to them than what you&#8217;ll be using in this project. In this project, you will use materials to change the color of the tile objects you have created. In the <em>Assets <\/em>window, double click the <em>Materials<\/em> folder you created earlier and right click in the <em>Assets <\/em>window again to bring up the same menu as before when you created the folders. This time go to <em>Create <\/em>and select <em>Material<\/em>.<\/p>\n<p>Give the name <em>White<\/em> to the new material you have created. Figure 10 shows your <em>Assets <\/em>window with the new material created.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"257\" height=\"124\" class=\"wp-image-77300\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-7.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 10: The newly created material.<\/p>\n<p>There&#8217;s nothing more to be done with this material, so go ahead and select the material and press Ctrl + D to make a copy of it. Click on the name of the newly created material to rename it. Call this material <em>Green<\/em> like in Figure 11.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"251\" height=\"79\" class=\"wp-image-77301\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-8.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 11: The Green and White materials.<\/p>\n<p>Of course, it doesn&#8217;t make much sense to call this material <em>Green <\/em>if it&#8217;s not actually green. With the <em>Green <\/em>material selected, go to the <em>Inspector <\/em>window and select the color picker towards the top as shown in Figure 12.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"566\" height=\"336\" class=\"wp-image-77302\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-9.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 12: Selecting the color picker. Note that there&#8217;s two options. You&#8217;ll want the white box.<\/p>\n<p>You&#8217;ll be greeted with Unity&#8217;s color picker. This is where you will set the color of the material. Give this material the RGB value of 0 red, 255 green, 0 blue, and 255 alpha (lowering the alpha will give you an invisible material, which won&#8217;t be helpful for this project). Figure 13 shows how to set the color of the <em>Green <\/em>material.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"315\" height=\"473\" class=\"wp-image-77303\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-10.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 13: The Unity color picker.<\/p>\n<p>Once the color has been set, select any of the two materials created so far and make three duplicates, bringing you to a total of five materials. Each of these materials will need their own name and color set for each. Table 1 shows the name of each material in alphabetical order and the RGB values for each one.<\/p>\n<p class=\"caption\">Table 1: All materials and their RGB values<\/p>\n<table class=\"table--tight\">\n<tbody>\n<tr>\n<td>\n<p><strong>Material<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Red Value<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Green Value<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Blue Value<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Alpha Value<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Blue<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Green<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Red<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>White<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Yellow<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<td>\n<p>0<\/p>\n<\/td>\n<td>\n<p>255<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>With all the materials created, go back to the <em>Hierarchy<\/em> window and give one of the following names to each <em>WhiteTile<\/em> copy you made earlier.<\/p>\n<ul>\n<li>BlueTile<\/li>\n<li>GreenTile<\/li>\n<li>RedTile<\/li>\n<li>YellowTile<\/li>\n<\/ul>\n<p>After giving your objects their new names your <em>Hierarchy<\/em> window should look like the one shown in Figure 14.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"275\" height=\"267\" class=\"wp-image-77304\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-11.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 14: Renamed objects in Hierarchy window.<\/p>\n<p>Now we need to set each object&#8217;s material. This way the object&#8217;s appearance will match its name. Start with the <em>BlueTile<\/em> object and go to the <em>Inspector <\/em>window. Under the component <em>Mesh Renderer<\/em> select <em>Materials<\/em> to bring down more information about the object&#8217;s material. Figure 15 shows where to find <em>Materials<\/em>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"565\" height=\"401\" class=\"wp-image-77305\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-12.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 15: Locating <em>Materials <\/em>in the object <em>Inspector<\/em> window.<\/p>\n<p>Here is where you set the color of the object using the material you created earlier. Since the <em>BlueTile<\/em> object is selected you will want to give it the <em>Blue <\/em>material. In your assets window, click and drag the <em>Blue<\/em> material into the <em>Element 0<\/em> field as shown in Figure 16.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"664\" height=\"435\" class=\"wp-image-77306\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-14.png\" \/><\/p>\n<p class=\"caption\">Figure 16: Setting the <em>Blue <\/em>material for the <em>BlueTile <\/em>object.<\/p>\n<p>The same process must be applied to every tile object in the <em>Hierarchy<\/em>. Table 2 shows each tile object and which material to set it to.<\/p>\n<p class=\"caption\">Table 2: All tile objects and their respective materials<\/p>\n<table class=\"table--tight\">\n<tbody>\n<tr>\n<td>\n<p><strong>Object<\/strong><\/p>\n<\/td>\n<td>\n<p><strong>Material<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>WhiteTile<\/p>\n<\/td>\n<td>\n<p>White<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>BlueTile<\/p>\n<\/td>\n<td>\n<p>Blue<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>GreenTile<\/p>\n<\/td>\n<td>\n<p>Green<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>RedTile<\/p>\n<\/td>\n<td>\n<p>Red<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>YellowTile<\/p>\n<\/td>\n<td>\n<p>Yellow<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the <em>Assets <\/em>window, select the <em>Tile Objects <\/em>folder created at the beginning. Figure 17 is a reminder as to where to find this.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"442\" height=\"126\" class=\"wp-image-77307\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-13.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 17: Locating the <em>Tile Objects <\/em>folder in the <em>Assets <\/em>window.<\/p>\n<p>With the <em>Tile Objects <\/em>folder select, click and drag each tile object from the <em>Hierarchy <\/em>window into the <em>Assets <\/em>window to make what&#8217;s known as a prefab for each object. Later on in the project, you will tell the computer to procedurally generate a map using these tiles, and the best way to do that is to create a prefab for each. A prefab is essentially a copy of an object created earlier that can be used in any place you want simply by either dragging it into the <em>Hierarchy<\/em> or, in this case, instantiating (creating) an object through code. Once you&#8217;ve dragged each tile object into the <em>TileObjects <\/em>folder your assets window (with the <em>TileObjects <\/em>folder selected) will look like the one seen in Figure 18.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"442\" height=\"157\" class=\"wp-image-77308\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-14.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 18: All tile prefabs needed for the project.<\/p>\n<p>You now have a copy of each tile that you can bring into the game world at any time in your assets, so you may now delete each of the tile objects in your <em>Hierarchy <\/em>window. With the objects deleted, create a new object in the <em>Hierarchy<\/em> window by clicking the <em>Create <\/em>button in the <em>Hierarchy<\/em> window and this time select <em>Create Empty. <\/em>Figure 19 shows where this option is.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"283\" height=\"292\" class=\"wp-image-77309\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-15.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 19: Creating a new empty object.<\/p>\n<p>Give the newly created object the name <em>Map Generator. <\/em>Once you&#8217;ve changed the name go to the <em>Inspector <\/em>window and select <em>Add Component <\/em>as seen in Figure 20.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"566\" height=\"258\" class=\"wp-image-77310\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-16.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 20: Adding a new component to the <em>Map Generator <\/em>object.<\/p>\n<p>Search for <em>New Script<\/em> using the search bar in the box that appears. When you&#8217;ve found it, select the <em>New Script <\/em>option. You will then be asked to give the new script a name and set the language. Give the script the name <em>MapGenerator <\/em>and be sure that the language is set to <em>C Sharp. <\/em>When finished, click <em>Create and Add <\/em> to create the new script and add it as a component to your <em>Map Generator <\/em>object. Figure 21 shows the script creation window.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"435\" height=\"512\" class=\"wp-image-77311\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-15.png\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 21: The script creation window.<\/p>\n<p>Finally, open the new script by double clicking the <em>Script <\/em>field in the newly created <em>MapGenerator <\/em>component. Figure 22 shows where to click to open the new script in Visual Studio.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" width=\"566\" height=\"231\" class=\"wp-image-77312\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-16.png\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 22: Selecting the <em>MapGenerator<\/em> script and opening Visual Studio.<\/p>\n<h2>Writing the Code<\/h2>\n<p>This script is going to create your map for you whenever you start the game. You will also have the program destroy the current map and make a new one whenever you press the mouse button. Along with the simple map creation process, you will also give the map generator some basic rules for how it should build out the map. Some of these rules are coded directly in the script, while other rules will be set from within the Unity editor. Above the <em>Start <\/em>function but below the class declaration, begin by declaring the following variables:<\/p>\n<pre class=\"lang:c# theme:vs2012\">  public GameObject[] tiles;\r\n  public int columns;\r\n  public int rows;\r\n  public int maxBlue = 100;\r\n  public int maxRed = 100;\r\n  public int maxYellow = 100;\r\n  public int maxGreen = 5;\r\n  public int howManyWhite = 30;\r\n  private int whiteTileCount;\r\n  private int greenTileCount;\r\n  private int redTileCount;\r\n  private int blueTileCount;\r\n  private int yellowTileCount;\r\n  private int tileToGenerate = 0;\r\n  private int resetHowManyWhite;<\/pre>\n<p>There&#8217;s a lot of variables declared right from the start. Some of them will seem simple to understand such as rows and columns while others are a little odd at first. The very first variable, the <strong>tiles<\/strong> array, will store the different tiles created earlier. After defining columns and rows, you&#8217;ll have created several variables that will control how many of a certain tile you&#8217;ll allow Unity to create in the map. This value can be changed from within the Unity editor, which you will do later. Beyond that comes the private integers, starting with the <strong>tileCount<\/strong> integers. These variables will be used to track the number of corresponding tiles created in a map. Finally, <strong>tileToGenerate<\/strong> will have its value changed to a random number whenever we create the next tile. Depending on the number Unity gets from a range you provide it, Unity then creates whichever tile that corresponds with that random number. The last variable, <strong>resetHowManyWhite<\/strong>, exists to assist when resetting the <strong>howManyWhite<\/strong> variable later on.<\/p>\n<p>With all the required variables created, it&#8217;s time to create the first function needed for the map generator. Below the <strong>Update<\/strong> function that Unity created, make a new void function called <strong>LoadMap().<\/strong><\/p>\n<pre class=\"lang:c# theme:vs2012\">void LoadMap()\r\n      {\r\n      }<\/pre>\n<p>Now inside the <strong>LoadMap()<\/strong> function write the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">  greenTileCount = 0;\r\n  whiteTileCount = 0;\r\n  redTileCount = 0;\r\n  blueTileCount = 0;\r\n  yellowTileCount = 0;\r\n  for (int x = 0; x &lt; rows; x++)\r\n  {\r\n  \tfor (int y = 0; y &lt; columns; y++)\r\n  \t{\r\n  \t\t\r\n  \t}\r\n  }<\/pre>\n<p>The first thing being done whenever the map is loaded is to reset the tile counts. This will be especially useful when creating new maps from a mouse click while playing the game. After that a for loop will be entered that will go through the <em>X <\/em>and <em>Y <\/em>coordinates of the map. It will cycle through this loop based on what you have set rows and columns to in the Unity editor.<\/p>\n<p>Before continuing to develop the <strong>LoadMap()<\/strong>, function you will need to create another function that <strong>LoadMap()<\/strong> will call. This function will take the tile the game was about to create and check the <strong>maxColor<\/strong> variables created at the start. If the tile the game is about to create would exceed the maximum number of allowed tiles in this map, then it will instead create a white tile. You can pretend that the white tiles represent \u2018basic floor\u2019 for this project. Below the <strong>LoadMap()<\/strong> function create the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">void CheckTile(int randomTile)\r\n   {\r\n  \tswitch (randomTile)\r\n  \t{\r\n  \t}\r\n  }<\/pre>\n<p>Begin with the <strong>CheckTile()<\/strong> function. Whenever this function is used in the <strong>LoadMap()<\/strong> function you will pass in the <strong>tileToGenerate<\/strong> variable as <strong>CheckTile()<\/strong>&#8216;s sole parameter. Then it will look at what this number is and check for a case that matches the value. For this project, this function will have five different cases, one for each type of tile, and a default case in case something goes wrong. Within the switch block and starting with case 0, enter the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">case 0:\r\n  \tif (greenTileCount &gt;= maxGreen - 1)\r\n  \t{\r\n  \t\ttileToGenerate = 1;\r\n  \t\twhiteTileCount++;\r\n  \t\thowManyWhite--;\r\n  \t\tbreak;\r\n  \t}\r\n  \telse\r\n  \t{\r\n  \t\tif (howManyWhite &lt;= 0)\r\n  \t\t{\r\n  \t\t\tgreenTileCount++;\r\n  \t\t\thowManyWhite = resetHowManyWhite;\r\n  \t\t\tbreak;\r\n  \t\t}\r\n  \t\telse\r\n  \t\t{\r\n  \t\t\ttileToGenerate = 1;\r\n  \t\t\twhiteTileCount++;\r\n  \t\t\thowManyWhite--;\r\n  \t\t\tbreak;\r\n  \t\t}\r\n  \t}<\/pre>\n<p>Case 0 is used when Unity is going to create a green tile. For this project pretend that a green tile is an exit for your map. First it looks to see if the number of green tiles already created is greater than or equal to the maximum number of green tiles minus one. You&#8217;re subtracting one from <strong>maxGreen<\/strong> in this instance since you&#8217;ll be setting up a rule later that forces a green tile to be created in a specific <em>X <\/em>and <em>Y <\/em>location on your map, and you don&#8217;t want more green tiles than allowed. If the number of green tiles is greater than the maximum green tiles minus one, then it will instead spawn a white tile by setting the <strong>tileToGenerate <\/strong>variable to one and then adding one to the <strong>whiteTileCount<\/strong> variable.<\/p>\n<p>From there, one is subtracted from the <strong>howManyWhite<\/strong> variable. However, if this is not true, the game asks another question. Is the <strong>howManyWhite<\/strong> variable less than or equal to zero? If so, then it&#8217;s okay to instantiate a green tile. Otherwise, create a white tile like before. The variable <strong>howManyWhite<\/strong> is in place to tell the game \u201cbefore you create any green tiles, have you at least created this many white tiles?\u201d If the answer is yes, then while it creates a green tile it will reset the number of white tiles to be created before permitting the game to create another green tile using the <strong>resetHowManyWhite<\/strong> variable.<\/p>\n<p>The next case is much simpler than case 0. Following the first case in our <strong>CheckTile()<\/strong> function, enter the following:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\tcase 1:\r\n                  whiteTileCount++;\r\n                  howManyWhite--;\r\n                  break;\r\n<\/pre>\n<p>If the <strong>tileToGenerate <\/strong>is equal to one, this will mean that the game is creating a white tile. Since for this project you&#8217;re pretending the white tile is a basic floor, we don&#8217;t need to do anything more. Increase the <strong>whiteTileCount<\/strong> variable by one and decrease <strong>howManyWhite<\/strong> by one.<\/p>\n<p>All the remaining cases follow a similar structure from here. Enter the following code after case 1:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\t\r\n           case 2:\r\n                  if (redTileCount &gt;= maxRed)\r\n                  {\r\n                      tileToGenerate = 1;\r\n                      whiteTileCount++;\r\n                      howManyWhite--;\r\n                      break;\r\n                  }\r\n                  else\r\n                  {\r\n                      redTileCount++;\r\n                      break;\r\n                  }\r\n              case 3:\r\n                  if (blueTileCount &gt;= maxBlue)\r\n                  {\r\n                      tileToGenerate = 1;\r\n                      whiteTileCount++;\r\n                      howManyWhite--;\r\n                      break;\r\n                  }\r\n                  else\r\n                  {\r\n                      blueTileCount++;\r\n                      break;\r\n                  }\r\n              case 4:\r\n                  if (yellowTileCount &gt;= maxYellow)\r\n                  {\r\n                      tileToGenerate = 1;\r\n                      whiteTileCount++;\r\n                      howManyWhite--;\r\n                      break;\r\n                  }\r\n                  else\r\n                  {\r\n                      yellowTileCount++;\r\n                      break;\r\n                  }<\/pre>\n<p>These cases are like a simpler version of case 0. They all check to see if its respective tile count has exceeded its corresponding maximum tile count. If so, you make the <strong>tileToGenerate<\/strong> variable equal one to create a white tile. Otherwise, we add one to the color&#8217;s tile count and continue from there.<\/p>\n<p>There&#8217;s one last case to make before this function is complete. If you do something wrong when setting the random range of numbers, you&#8217;ll have a default case to fall back on. This default case does the same thing as case 1. Below case 4 you&#8217;ll enter the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">default:\r\n                  whiteTileCount++;\r\n                  howManyWhite--;\r\n                  break;<\/pre>\n<p>With this final case created, your <strong>CheckTile()<\/strong> function is now complete. Figures 23 and 24 show the complete code for <strong>CheckTile().<\/strong><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"504\" height=\"663\" class=\"wp-image-77313\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-17.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 23: Part of the CheckTile() function.<\/p>\n<p>&nbsp;<\/p>\n<p class=\"caption\">\u00a0<img loading=\"lazy\" decoding=\"async\" width=\"504\" height=\"508\" class=\"wp-image-77314\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-18.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 24: Remainder of CheckTile() function.<\/p>\n<p>It&#8217;s time to complete the <strong>LoadMap()<\/strong> function. Within the second for loop, enter this code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">if (x &gt;= 0 &amp;&amp; x &lt; 3 &amp;&amp; y &gt;= 0 &amp;&amp; y &lt; 3)\r\n  {\r\n  \ttileToGenerate = 1;\r\n  \tCheckTile(tileToGenerate);\r\n  \tGameObject obj;\r\n  \tobj = Instantiate(tiles[tileToGenerate], new Vector3(x, 0, y), Quaternion.identity);\r\n  \tobj.transform.parent = transform;\r\n  }<\/pre>\n<p>This is one of the first rules you establish in your map generator. Simply put, this <strong>if <\/strong>statement will check the current coordinates. If they are within 0 and 3, it will place a white tile. You still use the <strong>CheckTile()<\/strong> function to handle adding to the number of white tiles created. Finally, you make that tile a child of the map generator object. This will make it easier to create a new map on mouse click when you add that functionality.<\/p>\n<p>The next few rules that will be set up for your map generator are as follows: first, there will be a rule that states that if the generator is on the very last tile, it will be forced to make it a green tile. Remember that you&#8217;re pretending the green tile is an exit tile, and a map is going to want at least one way out. This guarantees that there will be at least one exit in the map in a certain position every time a new map is loaded. After that, the next rule states that there will be a number of white tiles surrounding the last green tile the game instantiates, similar to the first rule where you tell the generator to start by making some white tiles. The final rule simply states to spawn a random tile in the <em>X <\/em>and <em>Y <\/em>location given to it. Below is the code for these different rules, beginning right after the if statement made earlier:<\/p>\n<pre class=\"lang:c# theme:vs2012\">else if (x == rows - 1 &amp;&amp; y == columns - 1)\r\n  {\r\n  \ttileToGenerate = 0;\r\n  \tgreenTileCount++;\r\n  \tGameObject obj;\r\n  \tobj = Instantiate(tiles[tileToGenerate], new Vector3(x, 0, y), Quaternion.identity);\r\n  \tobj.transform.parent = transform;\r\n  }\r\n  else if (x &gt;= rows - 3 &amp;&amp; y &gt;= columns - 3)\r\n  {\r\n  \ttileToGenerate = 1;\r\n  \tCheckTile(tileToGenerate);\r\n  \tGameObject obj;\r\n  \tobj = Instantiate(tiles[tileToGenerate], new Vector3(x, 0, y), Quaternion.identity);\r\n  \tobj.transform.parent = transform;\r\n  }\r\n  else\r\n  {\r\n  \tVector3 pos = new Vector3(x, 0, y);\r\n  \ttileToGenerate = Random.Range(0, 5);\r\n  \tCheckTile(tileToGenerate);\r\n  \tGameObject obj;\r\n  \tobj = Instantiate(tiles[tileToGenerate], new Vector3(x, 0, y), Quaternion.identity);\r\n  \tobj.transform.parent = transform;\r\n  }<\/pre>\n<p>Outside the <strong>for<\/strong> loop, near the bottom of the <strong>LoadMap()<\/strong> function, you will tell Unity to create a debug message informing you of how many of each type of tile the game has created. To do this you simply enter the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012 \">  Debug.Log(\"white tiles = \" + whiteTileCount);\r\n  Debug.Log(\"red tiles = \" + redTileCount);\r\n  Debug.Log(\"green tiles = \" + greenTileCount);\r\n  Debug.Log(\"blue tiles = \" + blueTileCount);\r\n  Debug.Log(\"yellow tiles = \" + yellowTileCount);<\/pre>\n<p>Now that you have Unity printing out debug messages to you, your <strong>LoadMap()<\/strong> function is complete. Figures 25 and 26 shows the completed code for <strong>LoadMap()<\/strong>.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"864\" height=\"640\" class=\"wp-image-77315\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-19.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 25: LoadMap() laying down rules for map generations<\/p>\n<p class=\"caption\">\u00a0<img loading=\"lazy\" decoding=\"async\" width=\"864\" height=\"331\" class=\"wp-image-77316\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-20.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 26: The final rule of LoadMap() and setting up the debug messages.<\/p>\n<p>Two small things must now be done before the code is complete. Add the following two lines of code to the <strong>Start()<\/strong> function:<\/p>\n<pre class=\"lang:c# theme:vs2012\">  resetHowManyWhite = howManyWhite;\r\n  LoadMap();<\/pre>\n<p>All this does is set the <strong>resetHowManyWhite<\/strong> variable to the value of <strong>howManyWhite<\/strong>, which will be useful when needing to reset the number of white tiles to be spawned before creating a green tile. Next, the game will create a new map. Both of these happen from the start of the game since we are using the <em>Start()<\/em> function. Now, in the <strong>Update()<\/strong> function add the following code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">  if (Input.GetMouseButtonDown(0))\r\n  {\r\n  \tforeach (Transform child in transform)\r\n  \t\tDestroy(child.gameObject);\r\n  \tLoadMap();\r\n  }<\/pre>\n<p>This will check if the left mouse button has been pressed, and if it has it will get each tile and destroy them. It does this by getting every child of the map generator object (remember that when we spawn new tiles we set them as children of the map generator) and destroying them from the game. It will then proceed to create a new map. Figure 27 shows the completed <strong>Start()<\/strong> and <strong>Update()<\/strong> functions.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"433\" height=\"289\" class=\"wp-image-77317\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-21.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 27: Completed Start() and Update() functions.<\/p>\n<p>A few things need to be set up in Unity before you can try out your new map generator. Save your code and go back to Unity.<\/p>\n<h2>Finishing Up<\/h2>\n<p>With the map generator complete, you will notice that the <em>MapGenerator<\/em> component in the <em>Inspector<\/em> window has several new fields. These have appeared because we declared these variables public. Figure 28 shows these new fields.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"224\" class=\"wp-image-77318\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-22.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 28: The newly created fields for you MapGenerator component.<\/p>\n<p>First, you need to define what the tiles are. Click on the <em>Tiles <\/em>field in the <em>MapGenerator <\/em>component. Clicking it will reveal a new field called <em>Size <\/em>as seen in Figure 29.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"224\" class=\"wp-image-77319\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-23.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 29: Opening the Tiles field to reveal Size.<\/p>\n<p>Set <em>Size <\/em>to 5. When you&#8217;ve done this five more fields will appear. Figure 30 shows these new fields.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"331\" class=\"wp-image-77320\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-24.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 30: Setting the Size field to create five new Element fields.<\/p>\n<p>These fields are where you will define your tile prefabs. Select the <em>Tile Objects<\/em> folder in the <em>Assets <\/em>window to find the tile prefabs created earlier in the project. The <em>WhiteTile <\/em>and <em>GreenTile <\/em>prefabs must be set in specific fields for your code to work as intended. Place <em>GreenTile <\/em>in the <em>Element 0<\/em> field and <em>WhiteTile <\/em>in <em>Element 1<\/em> like in Figure 31.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1006\" height=\"680\" class=\"wp-image-77321\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-25.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 31: Setting the GreenTile and WhiteTile prefabs to Element 0 and Element 1 respectively.<\/p>\n<p>The remaining <em>Element <\/em>fields can take any tile in any order, so place them into the <em>Element <\/em>fields as you like. Figure 32 shows the completed <em>Tiles <\/em>list.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"359\" class=\"wp-image-77322\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-26.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 32: The completed Tiles array.<\/p>\n<p>Now you should specify how many columns and rows there will be in your map. Go ahead and set <em>Columns <\/em>and <em>Rows <\/em>both to 20 like in Figure 33.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"562\" height=\"91\" class=\"wp-image-77323\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-27.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 33: Setting the Columns and Rows variables.<\/p>\n<p>All the other fields can be left at their default values for this project, but feel free to play with them later and see what sort of results you get. Finally, you need to readjust the camera to better view your map in the <em>Game<\/em> window. Select the <em>Main Camera <\/em>object from the <em>Hierarchy<\/em>. Then within the <em>Inspector <\/em>window you will change <em>Position X <\/em>to 10, <em>Position Y <\/em>to 26, and <em>Position Z <\/em>to 10. Finally, change <em>Rotation X <\/em>to equal 90 so that the camera is facing downward. Figure 34 shows where all these fields are.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"569\" height=\"138\" class=\"wp-image-77324\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-28.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 34: Adjusting the camera position and rotation.<\/p>\n<h2>Running the Game<\/h2>\n<p>Everything is now complete! Press the play button at the top of the Unity editor and watch Unity create a brand new map for you! While playing, press the left mouse button in the <em>Game<\/em> window to get a brand new map. Figure 35 shows an example map from the completed project.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"893\" height=\"361\" class=\"wp-image-77325\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-29.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 35: Example map created from the map generator.<\/p>\n<p>If you click near the bottom of the <em>Game<\/em> window like in Figure 36 you can also bring up the <em>Debug Log<\/em> which will display how many tiles of a certain color were created in a given map.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"463\" height=\"144\" class=\"wp-image-77326\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/02\/word-image-30.jpeg\" \/><\/p>\n<p class=\"caption\">Figure 36: Where to click to open the Debug Log.<\/p>\n<h2>Conclusion<\/h2>\n<p>You&#8217;ve been pretending throughout this project that white tiles are basic floor and green tiles are exit. In this example you could also imagine red tiles being walls or danger zones, yellow tiles being coins, and blue tiles being water. With this in mind, you can see the large variety of maps at your disposal. Change some of the values within the <em>MapGenerator <\/em>component and you will get different maps. If you wish for the player to get a lot of treasure in a certain level, up the number of yellow tiles and decrease the red and blue tiles. The possibilities are virtually endless!<\/p>\n<p>As mentioned before, it is not advisable to use what you&#8217;ve created today to make a full game. It is instead encouraged to use this as a starting point and make your own map generation system from there. There are many different additions you can make such as including more types of tiles, setting additional rules for when a certain tile should be created, and much more. What you do with it is entirely up to you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever wondered how game developers create the worlds in which the game lives? In this article, Lance demonstrates the basics of creating a map using a procedure in C#.&hellip;<\/p>\n","protected":false},"author":317499,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[],"coauthors":[52549],"class_list":["post-77290","post","type-post","status-publish","format-standard","hentry","category-dotnet-development"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77290","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/317499"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=77290"}],"version-history":[{"count":18,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77290\/revisions"}],"predecessor-version":[{"id":92058,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/77290\/revisions\/92058"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=77290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=77290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=77290"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=77290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}