Search Unity

My first dungeon generator in C#

Discussion in 'Scripting' started by Sea_Laszlo, Jul 24, 2014.

  1. Sea_Laszlo

    Sea_Laszlo

    Joined:
    Jun 13, 2013
    Posts:
    12
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq;
    5.  
    6. public class DungeonTest : MonoBehaviour {
    7.  
    8.     public int roomWidth = 10;
    9.     public int roomHeight = 10;
    10.     public int rooms = 3;
    11.  
    12.     private int roomsBuilt = 0;
    13.     private int xAxis, zAxis;
    14.     private List<Vector3> floorPoints = new List<Vector3>();
    15.     private List<Vector3> wallPoints = new List<Vector3>();
    16.     private List<Vector3> hallPoints = new List<Vector3>();
    17.     private bool drawMore = false;
    18.  
    19.     private RNG randomNumberGenerator;
    20.  
    21.     // Use this for initialization
    22.     void Start ()
    23.     {
    24.         DrawRoom(this.transform.position);
    25.      
    26.         // At the moment it only does three to four rooms well
    27.         if (drawMore.Equals(true))
    28.         {
    29.             for(int i = 0; i < rooms-1; i++)
    30.             {
    31.                 DrawRoom(floorPoints[floorPoints.Count-1]);
    32.             }
    33.         }
    34.          
    35.          
    36.     }
    37.  
    38.     void DrawRoom (Vector3 start)
    39.     {
    40.  
    41.        for(intx = 0; x < roomWidth; x++)
    42.        {
    43.           for(intz = 0; z < roomHeight; z++)
    44.           {
    45.              Vector3v3 = newVector3(start.x-(roomWidth-2)+x+xAxis,0,start.z-(roomHeight- 2)+z+zAxis);
    46.              wallPoints.Add(v3);
    47.  
    48.           //Subtract 2 to get the inside wall
    49.         if (x < roomWidth-2)
    50.         {
    51.             if (z < roomHeight-2)
    52.             {
    53.              //Don'ttouchthiseither, itworksmeow!
    54.              Vector3v3Output = newVector3((start.x-(xAxis*-1+x)),0,start.z-(zAxis*-1+z));
    55.              //Hallow out the wall points made earlier
    56.               wallPoints.Remove(v3Output);
    57.               floorPoints.Add(v3Output);
    58.              }
    59.          }
    60.  
    61.           }
    62.        }
    63.  
    64.         roomsBuilt++;
    65.      
    66.         if (roomsBuilt < rooms)
    67.         {
    68.             DrawDoor(0); // The zero is arbitrary
    69.         }
    70.     }
    71.  
    72.     void DrawDoor (int r)
    73.     {
    74.         int totalPoints = wallPoints.Count-1;
    75.      
    76.         randomNumberGenerator = new RNG();
    77.         int[] array = {1, 2, 3};
    78.      
    79.         for (int i = 0; i < array.Length; i++)
    80.         {
    81.             randomNumberGenerator.ShuffleArray(array);
    82.         }
    83.      
    84.         switch(array[0])
    85.         {
    86.             case 1:
    87.              
    88.                 r = randomNumberGenerator.SecureRandom(1,roomWidth-2); // Left Side
    89.                 print("Left Side");
    90.                 DrawHallway("Left",wallPoints[r]);
    91.                 break;
    92.              
    93.             case 2:
    94.              
    95.                 r = randomNumberGenerator.SecureRandom(totalPoints-roomWidth+2,totalPoints-1); // Right side
    96.                 print("Right Side");
    97.                 DrawHallway("Right",wallPoints[r]);
    98.                 break;
    99.              
    100.             case 3:
    101.              
    102.                 r = randomNumberGenerator.SecureRandom(roomWidth+1,totalPoints-roomWidth-1); // Top and   bottom are mixed, thanks to the (for) loop placement
    103.                 // Confused? Use some grid paper :D
    104.                 if (r % 2 != 0)
    105.                 {
    106.                     print("odd / Top"); // Top
    107.                     DrawHallway("Top",wallPoints[r]);
    108.                 }
    109.              
    110.                 else if (r % 2 == 0)
    111.                 {
    112.                     print("even / Bottom"); // Bottom
    113.                     DrawHallway("Bottom",wallPoints[r]);
    114.                 }
    115.                 break;
    116.         }
    117.      
    118.     }
    119.  
    120.     void DrawHallway (string buildSide, Vector3 Start)
    121.     {
    122.         // This swich steers the for loop in building in the correct direction
    123.         switch(buildSide)
    124.         {
    125.             case "Left":
    126.                 // - x
    127.                 xAxis = -1;
    128.                 break;
    129.              
    130.             case "Right":
    131.                 // + x
    132.                 xAxis = 1;
    133.                 break;
    134.              
    135.             case "Top":
    136.                 // + z
    137.                 zAxis = 1;
    138.                 break;
    139.              
    140.             case "Bottom":
    141.                 // - z
    142.                 zAxis = -1;
    143.                 break;
    144.         }
    145.      
    146.         // This is the length of the hallway, I put 15 a little longer than my 10x10 rooms
    147.         for(int a = 0; a < 15; a++)
    148.         {
    149.             Vector3 v3one = new Vector3(Start.x+(xAxis*a),0,Start.z+(zAxis*a));
    150.             floorPoints.Add(v3one);
    151.          
    152.             if (buildSide.Equals("Left"))
    153.             {
    154.                 Vector3 v3Offset1 = new Vector3(Start.x+(xAxis*a),0,1+Start.z+(zAxis*a));
    155.                 Vector3 v3Offset2 = new Vector3(Start.x+(xAxis*a),0,-1+Start.z+(zAxis*a));
    156.                 hallPoints.Add(v3Offset1);
    157.                 hallPoints.Add(v3Offset2);
    158.             }
    159.          
    160.             if (buildSide.Equals("Right"))
    161.             {
    162.                 Vector3 v3Offset1 = new Vector3(Start.x+(xAxis*a),0,1+Start.z+(zAxis*a));
    163.                 Vector3 v3Offset2 = new Vector3(Start.x+(xAxis*a),0,-1+Start.z+(zAxis*a));
    164.                 hallPoints.Add(v3Offset1);
    165.                 hallPoints.Add(v3Offset2);
    166.             }
    167.          
    168.              if (buildSide.Equals("Top")||buildSide.Equals("Bottom"))
    169.             {
    170.                 Vector3 v3Offset1 = new Vector3(1+Start.x+(xAxis*a),0,Start.z+(zAxis*a));
    171.                 Vector3 v3Offset2 = new Vector3(-1+Start.x+(xAxis*a),0,Start.z+(zAxis*a));
    172.                 hallPoints.Add(v3Offset1);
    173.                 hallPoints.Add(v3Offset2);
    174.             }
    175.          
    176.         }
    177.      
    178.      
    179.         if (roomsBuilt < rooms)
    180.         {
    181.             drawMore = true;
    182.             // Not reseting the xAxis and zAxis results in wonky hallways
    183.             xAxis = 0;
    184.             zAxis = 0;
    185.             floorPoints = floorPoints.Distinct().ToList(); // Remove overlapping floor points
    186.         }
    187.     }
    188.  
    189.     void OnDrawGizmosSelected()
    190.     {
    191.         // Paint the points in edit mode
    192.         foreach(Vector3 v3 in wallPoints)
    193.         {
    194.             Gizmos.color = Color.blue;
    195.             Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
    196.         }
    197.      
    198.         foreach(Vector3 v3 in hallPoints)
    199.         {
    200.             Gizmos.color = Color.red;
    201.             Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
    202.         }
    203.  
    204.         foreach(Vector3 v3 in floorPoints)
    205.         {
    206.             Gizmos.color = Color.white;
    207.             Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
    208.         }
    209.      
    210.     }
    211. }
    *You'll notice I don't use Unity's random range API, if you would like to use it here's the link to add it into your own code: http://docs.unity3d.com/ScriptReference/Random.Range.html

    This is my first attempt at a dungeon generator, so please critique away. It's the only way I get better.
    Thanks!
     
    Last edited: Jul 24, 2014
  2. mhtraylor

    mhtraylor

    Joined:
    Jan 13, 2013
    Posts:
    33
    No need to do two nested loops; you are already iterating over roomWidth * roomHeight, so you can perform the logic for those { x,z when x < roomWidth - 2, z < roomHeight - 2 } in that loop.
     
    Sea_Laszlo likes this.
  3. Sea_Laszlo

    Sea_Laszlo

    Joined:
    Jun 13, 2013
    Posts:
    12
    Thanks for the reply, I edited and re-ran the code everything works out. I think next I will add in some logic to keep the rooms a little separated. Every so often I notice two hallways side by side going to the same room, hilarious but not very realistic. What else? Oh, I am gonna add some logic for placing furniture.