Created
November 13, 2020 00:01
-
-
Save celechii/efa96fe7365f92ea9389df82f2f0ce3b to your computer and use it in GitHub Desktop.
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; | |
public class Maze : MonoBehaviour { | |
public Vector2Int mazeSize = new Vector2Int(15, 15); // this should b odd dimensions | |
[SerializeField] | |
public bool drawGizmos = true; | |
private bool[, ] maze; | |
private Vector2Int prevSize; // delete this, the OnValidate() method, n the OnDrawGizmos() method if u dont wanna preview it in the editor | |
[ContextMenu("Generate Maze")] | |
public bool[, ] GenerateMaze() { | |
maze = new bool[mazeSize.x, mazeSize.y]; | |
// random starting pos on an odd index position | |
Vector2Int startPos = new Vector2Int(Random.Range(0, (int)(mazeSize.x / 2f)), Random.Range(0, (int)(mazeSize.y / 2f))); | |
startPos *= 2; | |
startPos += Vector2Int.one; | |
maze[startPos.x, startPos.y] = true; | |
RecurseMaze(startPos.x, startPos.y); | |
return maze; | |
} | |
private void OnValidate() { | |
if (!drawGizmos) | |
return; | |
Vector2Int change = mazeSize - prevSize; | |
if (mazeSize.x <= 3) | |
mazeSize.x = 3; | |
if (mazeSize.y <= 3) | |
mazeSize.y = 3; | |
if (mazeSize.x % 2 == 0) | |
mazeSize.x += (int)Mathf.Sign(change.x); | |
if (mazeSize.y % 2 == 0) | |
mazeSize.y += (int)Mathf.Sign(change.y); | |
GenerateMaze(); | |
prevSize = mazeSize; | |
} | |
private void RecurseMaze(int xPos, int yPos) { | |
// shuffle the order u check the directions in | |
int[] randomDirs = new int[] {-1, -1, -1, -1 }; | |
for (int i = 0; i < randomDirs.Length; i++) { | |
int arrayPos; | |
do { | |
arrayPos = Random.Range(0, 4); | |
} while (randomDirs[arrayPos] != -1); | |
randomDirs[arrayPos] = i; | |
} | |
// go in each direction u can | |
for (int i = 0; i < randomDirs.Length; i++) { | |
// only run in this direction if its a valid one | |
if (IsValidDirection(randomDirs[i], xPos, yPos)) { | |
if (randomDirs[i] == 0) { // go up | |
maze[xPos, yPos + 1] = maze[xPos, yPos + 2] = true; | |
RecurseMaze(xPos, yPos + 2); | |
} else if (randomDirs[i] == 1) { // go down | |
maze[xPos, yPos - 1] = maze[xPos, yPos - 2] = true; | |
RecurseMaze(xPos, yPos - 2); | |
} else if (randomDirs[i] == 2) { // go left | |
maze[xPos - 1, yPos] = maze[xPos - 2, yPos] = true; | |
RecurseMaze(xPos - 2, yPos); | |
} else if (randomDirs[i] == 3) { // go right | |
maze[xPos + 1, yPos] = maze[xPos + 2, yPos] = true; | |
RecurseMaze(xPos + 2, yPos); | |
} | |
} | |
} | |
} | |
private bool IsValidDirection(int dir, int x, int y) { | |
if (dir == 0) | |
return IsValidPosition(x, y + 1) && IsValidPosition(x, y + 2); // up | |
if (dir == 1) | |
return IsValidPosition(x, y - 1) && IsValidPosition(x, y - 2); // down | |
if (dir == 2) | |
return IsValidPosition(x - 1, y) && IsValidPosition(x - 2, y); // left | |
if (dir == 3) | |
return IsValidPosition(x + 1, y) && IsValidPosition(x + 2, y); // right | |
return false; | |
bool IsValidPosition(int xPos, int yPos) { | |
return xPos >= 0 && xPos < mazeSize.x && yPos >= 0 && yPos < mazeSize.y && !maze[xPos, yPos]; | |
} | |
} | |
private void OnDrawGizmos() { | |
if (!drawGizmos) | |
return; | |
if (maze == null) | |
GenerateMaze(); | |
for (int x = 0; x < mazeSize.x; x++) { | |
for (int y = 0; y < mazeSize.y; y++) { | |
Vector2 offset = (Vector2)mazeSize / 2f; | |
if (x < 0 || x >= maze.GetLength(0) || y < 0 || y >= maze.GetLength(1)) | |
Gizmos.color = Color.black; | |
else | |
Gizmos.color = maze[x, y] ? Color.white : Color.black; | |
Gizmos.DrawCube(new Vector2(x, y) - offset, Vector2.one); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment