My first dungeon generator in C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class DungeonTest : MonoBehaviour {

    public int roomWidth = 10;
    public int roomHeight = 10;
    public int rooms = 3;
 
    private int roomsBuilt = 0;
    private int xAxis, zAxis;
    private List<Vector3> floorPoints = new List<Vector3>();
    private List<Vector3> wallPoints = new List<Vector3>();
    private List<Vector3> hallPoints = new List<Vector3>();
    private bool drawMore = false;
 
    private RNG randomNumberGenerator;
 
    // Use this for initialization
    void Start ()
    {
        DrawRoom(this.transform.position);
     
        // At the moment it only does three to four rooms well
        if (drawMore.Equals(true))
        {
            for(int i = 0; i < rooms-1; i++)
            {
                DrawRoom(floorPoints[floorPoints.Count-1]);
            }
        }
         
         
    }
 
    void DrawRoom (Vector3 start)
    {
 
       for(intx = 0; x < roomWidth; x++)
       {
          for(intz = 0; z < roomHeight; z++)
          {
             Vector3v3 = newVector3(start.x-(roomWidth-2)+x+xAxis,0,start.z-(roomHeight- 2)+z+zAxis);
             wallPoints.Add(v3);

          //Subtract 2 to get the inside wall
        if (x < roomWidth-2)
        {
            if (z < roomHeight-2)
            {
             //Don'ttouchthiseither, itworksmeow!
             Vector3v3Output = newVector3((start.x-(xAxis*-1+x)),0,start.z-(zAxis*-1+z));
             //Hallow out the wall points made earlier
              wallPoints.Remove(v3Output);
              floorPoints.Add(v3Output);
             }
         }

          }
       }
 
        roomsBuilt++;
     
        if (roomsBuilt < rooms)
        {
            DrawDoor(0); // The zero is arbitrary
        }
    }
 
    void DrawDoor (int r)
    {
        int totalPoints = wallPoints.Count-1;
     
        randomNumberGenerator = new RNG();
        int[] array = {1, 2, 3};
     
        for (int i = 0; i < array.Length; i++)
        {
            randomNumberGenerator.ShuffleArray(array);
        }
     
        switch(array[0])
        {
            case 1:
             
                r = randomNumberGenerator.SecureRandom(1,roomWidth-2); // Left Side
                print("Left Side");
                DrawHallway("Left",wallPoints[r]);
                break;
             
            case 2:
             
                r = randomNumberGenerator.SecureRandom(totalPoints-roomWidth+2,totalPoints-1); // Right side
                print("Right Side");
                DrawHallway("Right",wallPoints[r]);
                break;
             
            case 3:
             
                r = randomNumberGenerator.SecureRandom(roomWidth+1,totalPoints-roomWidth-1); // Top and   bottom are mixed, thanks to the (for) loop placement
                // Confused? Use some grid paper :smile:
                if (r % 2 != 0)
                {
                    print("odd / Top"); // Top
                    DrawHallway("Top",wallPoints[r]);
                }
             
                else if (r % 2 == 0)
                {
                    print("even / Bottom"); // Bottom
                    DrawHallway("Bottom",wallPoints[r]);
                }
                break;
        }
     
    }
 
    void DrawHallway (string buildSide, Vector3 Start)
    {
        // This swich steers the for loop in building in the correct direction
        switch(buildSide)
        {
            case "Left":
                // - x
                xAxis = -1;
                break;
             
            case "Right":
                // + x
                xAxis = 1;
                break;
             
            case "Top":
                // + z
                zAxis = 1;
                break;
             
            case "Bottom":
                // - z
                zAxis = -1;
                break;
        }
     
        // This is the length of the hallway, I put 15 a little longer than my 10x10 rooms
        for(int a = 0; a < 15; a++)
        {
            Vector3 v3one = new Vector3(Start.x+(xAxis*a),0,Start.z+(zAxis*a));
            floorPoints.Add(v3one);
         
            if (buildSide.Equals("Left"))
            {
                Vector3 v3Offset1 = new Vector3(Start.x+(xAxis*a),0,1+Start.z+(zAxis*a));
                Vector3 v3Offset2 = new Vector3(Start.x+(xAxis*a),0,-1+Start.z+(zAxis*a));
                hallPoints.Add(v3Offset1);
                hallPoints.Add(v3Offset2);
            }
         
            if (buildSide.Equals("Right"))
            {
                Vector3 v3Offset1 = new Vector3(Start.x+(xAxis*a),0,1+Start.z+(zAxis*a));
                Vector3 v3Offset2 = new Vector3(Start.x+(xAxis*a),0,-1+Start.z+(zAxis*a));
                hallPoints.Add(v3Offset1);
                hallPoints.Add(v3Offset2);
            }
         
             if (buildSide.Equals("Top")||buildSide.Equals("Bottom"))
            {
                Vector3 v3Offset1 = new Vector3(1+Start.x+(xAxis*a),0,Start.z+(zAxis*a));
                Vector3 v3Offset2 = new Vector3(-1+Start.x+(xAxis*a),0,Start.z+(zAxis*a));
                hallPoints.Add(v3Offset1);
                hallPoints.Add(v3Offset2);
            }
         
        }
     
     
        if (roomsBuilt < rooms)
        {
            drawMore = true;
            // Not reseting the xAxis and zAxis results in wonky hallways
            xAxis = 0;
            zAxis = 0;
            floorPoints = floorPoints.Distinct().ToList(); // Remove overlapping floor points
        }
    }
 
    void OnDrawGizmosSelected()
    {
        // Paint the points in edit mode
        foreach(Vector3 v3 in wallPoints)
        {
            Gizmos.color = Color.blue;
            Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
        }
     
        foreach(Vector3 v3 in hallPoints)
        {
            Gizmos.color = Color.red;
            Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
        }

        foreach(Vector3 v3 in floorPoints)
        {
            Gizmos.color = Color.white;
            Gizmos.DrawCube(v3, new Vector3(1, 1, 1));
        }
     
    }
}

*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: Unity - Scripting API: Random.Range

This is my first attempt at a dungeon generator, so please critique away. It’s the only way I get better.
Thanks!

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.

1 Like

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.