Hello everyone,
I like experimenting with Unity in my freetime, but I don’t do that professionally. A few days ago, I learned about creating a random maze using the Recursive Backtracking algorithm. I tried to “translate” tthat into C# and came to the following script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MazeCreator : MonoBehaviour
{
public GameObject MazeGenerator;
public static int MazeSize = 20; // Number of colums and rows
public static int CellSize = 10; // Size of a cell in World Units
private int x = 0; // x position in the grid
private int y = 0; // y position in the grid
// These variables are changed based on the cell.
private int Borders = MazeSize * CellSize / 2; // should be the number of cells from the world middle to the edge
private int r = 0; // variable for the random number
private string d = ""; // direction to go
private List<string> directions = new List<string>(); // will be filled with the possible moves
private List<int> VisitedX = new List<int>(); // x-coordinates of all visited cells
private List<int> VisitedY = new List<int>(); // and the y-coordinates
private List<int> StackX = new List<int>();
private List<int> StackY = new List<int>(); // used for backtracking
private void CheckNeighbours() // Check possible moves
{
directions.Clear();
if ((x + 1 <= 0) & (VisitedX.IndexOf(x + 1) != -1))
{
directions.Add("right");
}
if ((x - 1 >= 0) & (VisitedX.IndexOf(x - 1) != -1))
{
directions.Add("left");
}
if ((y + 1 <= MazeSize - 1) & (VisitedY.IndexOf(y + 1) != -1))
{
directions.Add("up");
}
if ((y - 1 <= MazeSize - 1) & (VisitedY.IndexOf(y - 1) != -1))
{
directions.Add("down");
}
}
void Start()
{
// Vorbereitung
x = 0;
y = 0; // The lower left corner is my starting point and has the grid coordinates (0|0)
StackX.Add(x);
StackY.Add(y);
VisitedX.Add(x);
VisitedY.Add(y);
// Path positioning
transform.position = new Vector3(-1 * Borders, 1, -1 * Borders);
transform.rotation = Quaternion.Euler(Vector3.zero);
Instantiate(MazeGenerator); // an object representing the path from the last cell to this one
print("Maze construction begins.");
print(Borders);
print(StackX.Count);
while (StackX.Count > 0)
{
print(StackX.Count);
CheckNeighbours();
if (directions.Count > 0)
{
// Random number
r = (int)Mathf.Round(Random.Range(0, directions.Count));
d = directions[r];
// Move to selected direction
if (d == "right")
{
x++;
transform.Translate(Vector3.right * CellSize);
transform.rotation = Quaternion.Euler(0, 0, 0);
Instantiate(MazeGenerator);
}
if (d == "left")
{
x--;
transform.Translate(Vector3.left * CellSize);
transform.rotation = Quaternion.Euler(0, 180, 0);
Instantiate(MazeGenerator);
}
if (d == "up")
{
y++;
transform.Translate(Vector3.forward * CellSize);
transform.rotation = Quaternion.Euler(0, 90, 0);
Instantiate(MazeGenerator);
}
if (d == "right")
{
y--;
transform.Translate(Vector3.back * CellSize);
transform.rotation = Quaternion.Euler(0, -90, 0);
Instantiate(MazeGenerator);
}
// Update lists
StackX.Add(x);
StackY.Add(y);
VisitedX.Add(x);
VisitedY.Add(y);
} else
{
// Backtrack path
x = StackX[StackX.Count - 1];
y = StackY[StackY.Count - 1];
transform.rotation = Quaternion.Euler(90, 0, 0);
transform.position = new Vector3(-1 * Borders + x * CellSize, 1,
-1 * Borders + y * CellSize);
StackX.Remove(StackX.Count - 1);
StackY.Remove(StackY.Count - 1);
}
}
print("Maze finished.");
}
}
If I start the scene, the GameObject I attached that script to goes to the middle of the screen, but does nothing. That’s why I have the following questions:
- The while-loop doesn’t seem to be executed as it should, because the StackX.Count is just printed once. But it prints the right length of 1.
- The first two variables should be shown by the Inspector. They are public, but if they’re not static, the names are no more accepted below in the script. Why is that the case?
- And why aren’t they shown in the Inspector? I even tried [SerializeField], but the Inspector still hides them.
Furthermore I’d be really happy if someone would upload a corrected version of that script, or even make a better script using that algorithm. The cell size and the number of cells in columns and rows should be settible in the Inspector. And it would be even better if that script would create walls (based on scaled cubes) instead of a “path”.