Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Delamare2112
Last active September 11, 2017 08:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Delamare2112/16978f2156fc5b4c917f to your computer and use it in GitHub Desktop.
Save Delamare2112/16978f2156fc5b4c917f to your computer and use it in GitHub Desktop.
A unity script that procedurally generates a map given rooms and pickups
using UnityEngine;
using System.Collections;
using System.Linq;
public class MapGenerator : MonoBehaviour
{
public Room[] roomPrefabs;
public Item[] itemPrefabs;
public int rows,columns;
public float roomWidth, roomHeight, itemDropChance;
public Player playerPrefab;
[Tooltip("Set to 0 to stop the ovveride")]
public int seedOvveride = 0;
private Room[] grid;
private int shuffledRoomsIndex = 0;
void Start()
{
if(seedOvveride != 0)
Random.seed = seedOvveride;
if(GameManager.seed != 0)
Random.seed = GameManager.seed;
Helpers.Shuffle(roomPrefabs);
GenerateGrid();
GenerateMaze();
}
private void GenerateGrid()
{
grid = new Room[rows * columns]; // recreate our grid with a valid size
// Foreach room
for(int row=0; row < rows; row++) for(int column=0; column < columns; column++)
{
// Create room at position
Room room = Instantiate(RandomRoomPrefab(), new Vector3(roomWidth * column, 0f, roomHeight * row), Quaternion.identity) as Room;
room.transform.parent = transform; // parent them as to keep heigherIkea clean.
room.name = "Room: " + column + ", " + row; // Nice name dude!
grid[Vector2ToIndex(new Vector2(column, row))] = room.GetComponent<Room>(); // store the room to our grid array
if(itemPrefabs.Length != 0 && Random.Range(0f, 100f) <= itemDropChance)
Instantiate(itemPrefabs[Random.Range(0, itemPrefabs.Length)], room.transform.position + new Vector3(0, 1.25f, +7f), Quaternion.identity);
}
// Foreach grid item
for(int i=0; i < grid.Length; i++)
{
// Let our rooms know whats next to eachother
grid[i].southRoom = i > columns ? grid[i - columns] : null;
grid[i].northRoom = i < (grid.Length-1) - columns ? grid[i + columns] : null;
grid[i].westRoom = i % columns != 0 ? grid[i-1] : null;
grid[i].eastRoom = i % columns != columns-1 ? grid[i+1] : null;
}
}
private void GenerateMaze()
{
Stack roomStack = new Stack();
Room currentRoom = grid[Random.Range(0, grid.Length)];
Instantiate(playerPrefab, currentRoom.transform.position + new Vector3(0, 1.25f, -7f), Quaternion.identity);
// Foreach room in grid
for(int i=1; i < grid.Length; i++)
{
ArrayList unvisitedNeighbors = GetUnvisitedNeighbors(currentRoom);
if(unvisitedNeighbors.Count <= 0) // if no unvisited found
currentRoom = roomStack.Pop() as Room; // Take a step back
else
{
Room next = unvisitedNeighbors[Random.Range(0, unvisitedNeighbors.Count)] as Room;
if(currentRoom.northRoom == next)
{
currentRoom.northDoor.SetActive(false);
next.southDoor.SetActive(false);
}
else if(currentRoom.southRoom == next)
{
currentRoom.southDoor.SetActive(false);
next.northDoor.SetActive(false);
}
else if(currentRoom.eastRoom == next)
{
currentRoom.eastDoor.SetActive(false);
next.westDoor.SetActive(false);
}
else if(currentRoom.westRoom == next)
{
currentRoom.westDoor.SetActive(false);
next.eastDoor.SetActive(false);
}
roomStack.Push(currentRoom);
currentRoom = next;
}
}
if(GameManager.isMultiplayer)
Instantiate(playerPrefab, currentRoom.transform.position + new Vector3(0, 1.25f, -7f), Quaternion.identity);
}
private ArrayList GetUnvisitedNeighbors(Room room)
{
ArrayList list = new ArrayList();
if(room.northRoom != null && !room.northRoom.IsVisited())
list.Add(room.northRoom);
if(room.southRoom != null && !room.southRoom.IsVisited())
list.Add(room.southRoom);
if(room.eastRoom != null && !room.eastRoom.IsVisited())
list.Add(room.eastRoom);
if(room.westRoom != null && !room.westRoom.IsVisited())
list.Add(room.westRoom);
return list;
}
private Room RandomRoomPrefab()
{
if(shuffledRoomsIndex == roomPrefabs.Length)
{
Helpers.Shuffle(roomPrefabs);
shuffledRoomsIndex = 0;
}
shuffledRoomsIndex++;
return roomPrefabs[shuffledRoomsIndex - 1];
}
private int Vector2ToIndex(Vector2 vector)
{
return (int)((vector.y * columns) + vector.x);
}
private Vector2 indexToVector2(int index)
{
return new Vector2(index % columns, Mathf.FloorToInt(index / columns));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment