I’m creating this 2D random dungeon generator and I’m having trouble trying to figure out how I can make the instance of the tileset not duplicate each other like the photo below.
In this picture is an example that on the side walls to the left there is a corner that duplicates itself all through the way instead of being the sidewall. And that’s what I’m trying to fix.
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LeveGenerator : MonoBehaviour
{
enum gridSpace { empty, floor, wall ,sidewallR, sidewallL, CornerTopLeft, CornerTopRight, CornerBottomLeft, CornerBottomRight, BottomWall,Player };
gridSpace[, ] grid;
public int roomHeight, roomWidth;
[Header("Room Settings")]
public Vector2 roomSizeWorldUnits = new Vector2(30, 30);
public float worldUnitsInOneGridCell = 1;
public struct walker
{
public Vector2 dir;
public Vector2 pos;
}
public List<walker> walkers;
public float chanceWalkerChangeDir = 0.5f, chanceWalkerSpawn = 0.05f;
public float chanceWalkerDestoy = 0.05f;
public int maxWalkers = 10;
public float percentToFill = 0.2f;
public int spawnNum = 0;
private Replace rp;
private LeveGenerator Gen;
[Header("Object Spawn Rate")]
public float chanceToSpawnEnemy = 0.2f;
public float chanceToSpawnItem = 0.5f;
public GameObject Enemy;
public GameObject Items;
[Header("Object Tileset")]//setup tile sets
public GameObject wallObj;
public GameObject floorObj;
public GameObject sidewallR;
public GameObject sidewallL;
public GameObject CornerTopLeft;
public GameObject CornerTopRight;
public GameObject CornerBottomLeft;
public GameObject CornerBottomRight;
public GameObject BottomWall;
[Header("Player")]
public GameObject Player;
void Start()
{
Setup();
CreateFloors();
CreateWalls();
RemoveSingleWalls();
//RemoveSideWall();
SpawnLevel();
SpawnObjects();
SpawnPlayer();
}
public void SpawnPlayer() {
for (int x = 0; x < roomWidth; x++)
{
for (int y = 0; y < roomHeight; y++)
{
if (grid[x, y] == gridSpace.floor && spawnNum < 1)
{
spawnNum++; //spawns player once
Spawn(x, y, Player);
}
}
}
}
public void SpawnObjects() {
for (int x = 0; x < roomWidth; x++)
{
for (int y = 0; y < roomHeight; y++)
{
if(grid[x, y] == gridSpace.floor &&
Random.value < chanceToSpawnEnemy){
Spawn(x, y, Enemy);
}
}
}
for (int x = 0; x < roomWidth; x++)
{
for (int y = 0; y < roomHeight; y++)
{
if (grid[x, y] == gridSpace.floor &&
Random.value < chanceToSpawnItem)
{
Spawn(x, y, Items);
}
}
}
}
public void Setup()
{
//find grid size
roomHeight = Mathf.RoundToInt(roomSizeWorldUnits.x / worldUnitsInOneGridCell);
roomWidth = Mathf.RoundToInt(roomSizeWorldUnits.y / worldUnitsInOneGridCell);
//create grid
grid = new gridSpace[roomWidth, roomHeight];
//set grid's default state
for (int x = 0; x < roomWidth - 1; x++)
{
for (int y = 0; y < roomHeight - 1; y++)
{
//make every cell "empty"
grid[x, y] = gridSpace.empty;
}
}
//set first walker
//init list
walkers = new List<walker>();
//create a walker
walker newWalker = new walker();
newWalker.dir = RandomDirection();
//find center of grid
Vector2 spawnPos = new Vector2(Mathf.RoundToInt(roomWidth / 2.0f),
Mathf.RoundToInt(roomHeight / 2.0f));
newWalker.pos = spawnPos;
//add walker to list
walkers.Add(newWalker);
}
public void CreateFloors()
{
int iterations = 0;//loop will not run forever
do
{
//create floor at position of every walker
foreach (walker myWalker in walkers)
{
grid[(int)myWalker.pos.x, (int)myWalker.pos.y] = gridSpace.floor;
}
//chance: destroy walker
int numberChecks = walkers.Count; //might modify count while in this loop
for (int i = 0; i < numberChecks; i++)
{
//only if its not the only one, and at a low chance
if (Random.value < chanceWalkerDestoy && walkers.Count > 1)
{
walkers.RemoveAt(i);
break; //only destroy one per iteration
}
}
//chance: walker pick new direction
for (int i = 0; i < walkers.Count; i++)
{
if (Random.value < chanceWalkerChangeDir)
{
walker thisWalker = walkers*;*
thisWalker.dir = RandomDirection();
walkers = thisWalker;
}
}
//chance: spawn new walker
numberChecks = walkers.Count; //might modify count while in this loop
for (int i = 0; i < numberChecks; i++)
{
//only if # of walkers < max, and at a low chance
if (Random.value < chanceWalkerSpawn && walkers.Count < maxWalkers)
{
//create a walker
walker newWalker = new walker();
newWalker.dir = RandomDirection();
newWalker.pos = walkers*.pos;*
walkers.Add(newWalker);
}
}
//move walkers
for (int i = 0; i < walkers.Count; i++)
{
walker thisWalker = walkers*;*
thisWalker.pos += thisWalker.dir;
walkers = thisWalker;
}
//avoid boarder of grid
for (int i = 0; i < walkers.Count; i++)
{
walker thisWalker = walkers*;*
//clamp x,y to leave a 1 space boarder: leave room for walls
thisWalker.pos.x = Mathf.Clamp(thisWalker.pos.x, 1, roomWidth - 2);
thisWalker.pos.y = Mathf.Clamp(thisWalker.pos.y, 1, roomHeight - 2);
walkers = thisWalker;
}
//check to exit loop
if ((float)NumberOfFloors() / (float)grid.Length > percentToFill)
{
break;
}
iterations++;
} while (iterations < 100000);
}
public void CreateWalls()
{
//loop though every grid space
for (int x = 0; x < roomWidth - 1; x++)
{
for (int y = 0; y < roomHeight - 1; y++)
{
//if theres a floor, check the spaces around it
if (grid[x, y] == gridSpace.floor)//
{
//if any surrounding spaces are empty, place a wall
if (grid[x, y + 1] == gridSpace.empty)//TOP WALL
{
grid[x, y + 1] = gridSpace.wall;
}
if (grid[x, y - 1] == gridSpace.empty)//BOTTOM WALL
{
grid[x, y - 1] = gridSpace.wall;
}
if (grid[x + 1, y] == gridSpace.empty)//SIDEWALL RIGHT
{
grid[x + 1, y] = gridSpace.sidewallR;
}
if (grid[x - 1, y] == gridSpace.empty)//SIDEWALL LEFT
{
grid[x - 1, y] = gridSpace.sidewallL;
}
if (grid[x - 1, y - 1] == gridSpace.empty )//Bottom Coner left
{
grid[x - 1, y - 1] = gridSpace.CornerBottomLeft;
}
//working on this
if (grid[x - 1, y + 1] == gridSpace.empty)
{
grid[x - 1, y + 1] = gridSpace.CornerTopLeft;
}
}
}
}
}
public void SpawnLevel()
{
for (int x = 0; x < roomWidth; x++)
{
for (int y = 0; y < roomHeight; y++)
{
switch (grid[x, y])
{
case gridSpace.empty:
break;
case gridSpace.floor:
Spawn(x, y, floorObj);
break;
case gridSpace.wall:
Spawn(x, y, wallObj);
break;
case gridSpace.sidewallR:
Spawn(x, y, sidewallR);
break;
case gridSpace.sidewallL:
Spawn(x, y, sidewallL);
break;
case gridSpace.CornerBottomLeft:
Spawn(x, y, CornerBottomLeft);
break;
case gridSpace.CornerTopLeft:
Spawn(x, y, CornerTopLeft);
break;
}
}
}
}
public void RemoveSingleWalls()
{
//loop though every grid space
for (int x = 0; x < roomWidth - 1; x++)
{
for (int y = 0; y < roomHeight - 1; y++)
{
//if theres a wall, check the spaces around it
if (grid[x, y] == gridSpace.wall)
{
//assume all space around wall are floors
bool allFloors = true;
//check each side to see if they are all floors
for (int checkX = -1; checkX <= 1; checkX++)
{
for (int checkY = -1; checkY <= 1; checkY++)
{
if (x + checkX < 0 || x + checkX > roomWidth - 1 ||
y + checkY < 0 || y + checkY > roomHeight - 1)
{
//skip checks that are out of range
continue;
}
if ((checkX != 0 && checkY != 0) || (checkX == 0 && checkY == 0))
{
//skip corners and center
continue;
}
if (grid[x + checkX, y + checkY] != gridSpace.floor)
{
allFloors = false;
}
}
}
if (allFloors)
{
grid[x, y] = gridSpace.floor;
}
}
}
}
}
/*
public void RemoveSideWall()
{
//loop though every grid space
for (int x = 0; x < roomWidth - 1; x++)
{
for (int y = 0; y < roomHeight - 1; y++)
{
//if theres a wall, check the spaces around it
if (grid[x, y] == gridSpace.sidewallL)
{
//assume all space around wall are floors
bool allFloors = true;
//check each side to see if they are all floors
for (int checkX = -1; checkX <= 1; checkX++)
{
for (int checkY = -1; checkY <= 1; checkY++)
{
if (x + checkX < 0 || x + checkX > roomWidth - 1 ||
y + checkY < 0 || y + checkY > roomHeight - 1)
{
//skip checks that are out of range
continue;
}
if ((checkX != 0 && checkY != 0) || (checkX == 0 && checkY == 0))
{
//skip corners and center
//allFloors = true;
continue;
}
if (grid[x + checkX, y + checkY] != gridSpace.floor)
{
allFloors = true;
}
}
}
if (allFloors)
{
grid[x, y] = gridSpace.floor;
}
}
}
}
}
*/
public Vector2 RandomDirection()
{
//pick random int between 0 and 3
int choice = Mathf.FloorToInt(Random.value * 3.99f);
//use that int to chose a direction
switch (choice)
{
case 0:
return Vector2.down;
case 1:
return Vector2.left;
case 2:
return Vector2.up;
default:
return Vector2.right;
}
}
int NumberOfFloors()
{
int count = 0;
foreach (gridSpace space in grid)
{
if (space == gridSpace.floor)
{
count++;
}
}
return count;
}
public void Spawn(float x, float y, GameObject toSpawn)
{
//find the position to spawn
Vector2 offset = roomSizeWorldUnits / 2.0f;
Vector2 spawnPos = new Vector2(x, y) * worldUnitsInOneGridCell - offset;
//spawn object
Instantiate(toSpawn, spawnPos, Quaternion.identity);
}
public void Update()
{
if (Input.GetButtonDown(“Jump”)) {
Restart();
}
}
public void Restart()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}