Skip to content

Instantly share code, notes, and snippets.

@Kutejnikov
Last active January 15, 2022 17:21
Show Gist options
  • Save Kutejnikov/bc89aee11330ae44c27d74c0ba4172fd to your computer and use it in GitHub Desktop.
Save Kutejnikov/bc89aee11330ae44c27d74c0ba4172fd to your computer and use it in GitHub Desktop.
A simple dungeon creation script for C# (with visualization in Unity)
// 1. Create UI -> Image
// 2. Add this script to Image
// 3. Press Space in Game Mode
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class RecursiveDungeon : MonoBehaviour
{
[SerializeField] Image image;
[SerializeField] int mapSizeHorizontal = 121;
[SerializeField] int mapSizeVertical = 81;
[SerializeField] int roomMinHorizontal = 11;
[SerializeField] int roomMinVertical = 9;
[SerializeField] int extraDoorChance = 15;
[SerializeField] int minLengthForExtraDoor = 40;
[SerializeField] int mapScale = 2;
int[,] maze;
void Awake()
{
image = GetComponent<Image>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) CreateDungeon();
}
void CreateDungeon()
{
if (mapSizeHorizontal % 2 == 0) mapSizeHorizontal++; // Odd numbers only.
if (mapSizeVertical % 2 == 0) mapSizeVertical++; // Odd numbers only.
maze = new int[mapSizeHorizontal, mapSizeVertical];
Division(1, mapSizeHorizontal - 2, 1, mapSizeVertical - 2);
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, mapSizeHorizontal * mapScale);
image.rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, mapSizeVertical * mapScale);
Texture2D texture = new Texture2D(mapSizeHorizontal, mapSizeVertical);
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, mapSizeHorizontal, mapSizeVertical), Vector2.zero);
sprite.texture.filterMode = FilterMode.Point;
image.sprite = sprite;
for (int x = 0; x < mapSizeHorizontal; x++)
{
for (int y = 0; y < mapSizeVertical; y++)
{
if (x == 0 || y == 0 || x == mapSizeHorizontal - 1 || y == mapSizeVertical - 1) maze[x, y] = 1;
Color pixelColour = Color.black;
if (maze[x, y] == 1) pixelColour = Color.white; // wall
else if (maze[x, y] == 2) pixelColour = Color.black; // door
texture.SetPixel(x, y, pixelColour);
}
}
texture.Apply();
}
void Division(int startX, int endX, int startY, int endY)
{
if (endX - startX + 1 < roomMinHorizontal * 2 && endY - startY + 1 < roomMinVertical * 2) return;
if (endX - startX > endY - startY)
{
if (endX - startX + 1 < roomMinHorizontal * 2) return;
CreateRoom(true, startX, endX, startY, endY);
}
else if (endX - startX < endY - startY)
{
if (endY - startY + 1 < roomMinVertical * 2) return;
CreateRoom(false, startX, endX, startY, endY);
}
else
{
if (Random.value > 0.5f)
{
if (endX - startX + 1 < roomMinHorizontal * 2) return;
CreateRoom(true, startX, endX, startY, endY);
}
else
{
if (endY - startY + 1 < roomMinVertical * 2) return;
CreateRoom(false, startX, endX, startY, endY);
}
}
}
void CreateRoom(bool isHorizontal, int startX, int endX, int startY, int endY)
{
if (isHorizontal)
{
int verticalWall = Random.Range((startX + roomMinHorizontal), endX + 1 - roomMinHorizontal);
if (verticalWall % 2 == 0) // Odd numbers only.
{
verticalWall++;
if (verticalWall >= (endX + 1 - roomMinHorizontal)) verticalWall -= 2;
}
for (int i = startY; i <= endY; i++)
{
maze[verticalWall, i] = 1;
}
int doorNumbers = 1;
if (extraDoorChance > Random.Range(0, 100) && endY - startY >= minLengthForExtraDoor) doorNumbers++;
for (int i = 0; i < doorNumbers; i++)
{
int randomDoor = Random.Range(startY, endY + 1);
if (randomDoor % 2 != 0)
{
randomDoor++;
if (randomDoor > endY) randomDoor -= 2;
}
maze[verticalWall, randomDoor] = 2;
}
Division(startX, verticalWall - 1, startY, endY);
Division(verticalWall + 1, endX, startY, endY);
}
else
{
int horizontalWall = Random.Range(startY + roomMinVertical, endY + 1 - roomMinVertical);
if (horizontalWall % 2 == 0) // Odd numbers only.
{
horizontalWall++;
if (horizontalWall >= endY + 1 - roomMinVertical) horizontalWall -= 2;
}
for (int i = startX; i <= endX; i++)
{
maze[i, horizontalWall] = 1;
}
int doorNumbers = 1;
if (extraDoorChance > Random.Range(0, 100) && endX - startX >= minLengthForExtraDoor) doorNumbers++;
for (int i = 0; i < doorNumbers; i++)
{
int randomDoor = Random.Range(startX, endX + 1);
if (randomDoor % 2 != 0)
{
randomDoor++;
if (randomDoor > endX) randomDoor -= 2;
}
maze[randomDoor, horizontalWall] = 2;
}
Division(startX, endX, startY, horizontalWall - 1);
Division(startX, endX, horizontalWall + 1, endY);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment