Last active
September 11, 2017 08:07
-
-
Save Delamare2112/16978f2156fc5b4c917f to your computer and use it in GitHub Desktop.
A unity script that procedurally generates a map given rooms and pickups
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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