using UnityEngine; using System.Collections; using System.Collections.Generic; public class MazeGenerator : MonoBehaviour { public int mazeWidth = 20; // Ширина лабиринта в ячейках public int mazeHeight = 20; // Высота лабиринта в ячейках public float cellSize = 1.5f; // Размер каждой ячейки public float wallThickness = 0f; // Толщина стен public float wallHeight = 1f; // Толщина стен public GameObject northPrefab; // Префаб стены public GameObject southPrefab; // Префаб стены public GameObject eastPrefab; // Префаб стены public GameObject westPrefab; // Префаб стены public GameObject floorPrefab1; // Префаб пола public GameObject floorPrefab2; // Префаб пола public GameObject floorPrefab3; // Префаб пола public GameObject floorPrefab4; // Префаб пола public GameObject upperPrefab; // Префаб пола public Transform mazeParent; // Родительский объект для элементов лабиринта public GameObject LightStick; //префаб ФОНАРЯ СО СВЕТОМ public Vector3 mazeOffset; // Смещение лабиринта (установим позже) private Cell[,] grid; void Start() { // Параметры двери float doorX = 5f; float doorZ = 0f; float passageWidth = 2f; // Настройка смещения лабиринта InitializeMaze(); // Начинаем генерацию лабиринта с произвольной точки int startX = Random.Range(0, mazeWidth); int startZ = Random.Range(0, mazeHeight); GenerateMaze(startX, startZ); CreateMazeEntrance(); CreateMazeExit(); } void InitializeMaze() { grid = new Cell[mazeWidth, mazeHeight]; for (int x = 0; x < mazeWidth; x++) { for (int z = 0; z < mazeHeight; z++) { Cell cell = new Cell(); // Позиция центра ячейки Vector3 cellPos = new Vector3(x * cellSize, 0, z * cellSize) + mazeOffset; Vector3 upperPos = new Vector3(x * cellSize, 10, z * cellSize) + mazeOffset; Vector3 bottPos = new Vector3(x * cellSize, 0.3f, z * cellSize) + mazeOffset; Vector3 backupperPos = new Vector3(x * cellSize, 10.1f, z * cellSize) + mazeOffset; Vector3 lightPos = new Vector3(x * cellSize -3, 0, z * cellSize - 3) + mazeOffset; // Случайная генерация пола int floorType = Random.Range(1, 5); switch (floorType) { case 1: cell.floor = Instantiate(floorPrefab1, bottPos, Quaternion.identity, mazeParent); break; case 2: cell.floor = Instantiate(floorPrefab2, bottPos, Quaternion.identity, mazeParent); break; case 3: cell.floor = Instantiate(floorPrefab3, bottPos, Quaternion.identity, mazeParent); break; case 4: cell.floor = Instantiate(floorPrefab4, bottPos, Quaternion.identity, mazeParent); break; } cell.floor.transform.localScale = new Vector3(0.904f, 4f, 0.901f); // Добавление фонарей в каждом 4-м столбце и строке if (((x % 3 == 0 && z % 3 == 0 && Random.value < 0.65f) || (Random.value < 0.1f)) && (x > 2 && z > 2)) { cell.lightstick = Instantiate(LightStick, lightPos, Quaternion.identity, mazeParent); } // Создание пола cell.upper = Instantiate(upperPrefab, upperPos, Quaternion.identity, mazeParent); cell.upper.transform.localScale = new Vector3(1f, -3f, 1f); cell.upper = Instantiate(upperPrefab, backupperPos, Quaternion.identity, mazeParent); cell.upper.transform.localScale = new Vector3(1f, 1f, 1f); southPrefab = northPrefab; westPrefab = northPrefab; eastPrefab = northPrefab; // Параметры стен float halfCell = cellSize / 2f; // Создание северной стены Vector3 northWallPos = cellPos + new Vector3(0, 1, halfCell); GameObject northWall = Instantiate(northPrefab, northWallPos, Quaternion.identity, mazeParent); northWall.transform.localScale = new Vector3(0.8f, 1, 1); cell.northWall = northWall; // Создание южной стены Vector3 southWallPos = cellPos + new Vector3(0, 1, -halfCell); GameObject southWall = Instantiate(southPrefab, southWallPos, Quaternion.identity, mazeParent); southWall.transform.localScale = new Vector3(0.8f, 1, 1); cell.southWall = southWall; // Создание восточной стены Vector3 eastWallPos = cellPos + new Vector3(halfCell, 1, 0); GameObject eastWall = Instantiate(eastPrefab, eastWallPos, Quaternion.identity, mazeParent); eastWall.transform.Rotate(0, 90, 0); eastWall.transform.localScale = new Vector3(0.8f, 1, 1); cell.eastWall = eastWall; // Создание западной стены Vector3 westWallPos = cellPos + new Vector3(-halfCell, 1, 0); GameObject westWall = Instantiate(westPrefab, westWallPos, Quaternion.identity, mazeParent); westWall.transform.Rotate(0, 90, 0); westWall.transform.localScale = new Vector3(0.8f, 1, 1); cell.westWall = westWall; grid[x, z] = cell; } } } void GenerateMaze(int x, int z) { grid[x, z].visited = true; List neighbors = GetUnvisitedNeighbors(x, z); while (neighbors.Count > 0) { Vector2Int chosenNeighbor = neighbors[Random.Range(0, neighbors.Count)]; int nx = chosenNeighbor.x; int nz = chosenNeighbor.y; if (!grid[nx, nz].visited) { RemoveWalls(grid[x, z], grid[nx, nz], x - nx, z - nz); GenerateMaze(nx, nz); } neighbors = GetUnvisitedNeighbors(x, z); } } List GetUnvisitedNeighbors(int x, int z) { List neighbors = new List(); if (x > 0 && !grid[x - 1, z].visited) neighbors.Add(new Vector2Int(x - 1, z)); if (x < mazeWidth - 1 && !grid[x + 1, z].visited) neighbors.Add(new Vector2Int(x + 1, z)); if (z > 0 && !grid[x, z - 1].visited) neighbors.Add(new Vector2Int(x, z - 1)); if (z < mazeHeight - 1 && !grid[x, z + 1].visited) neighbors.Add(new Vector2Int(x, z + 1)); return neighbors; } void RemoveWalls(Cell current, Cell neighbor, int dx, int dz) { if (dx == 1) { // Сосед на западе Destroy(current.westWall); Destroy(neighbor.eastWall); } else if (dx == -1) { // Сосед на востоке Destroy(current.eastWall); Destroy(neighbor.westWall); } if (dz == 1) { // Сосед на юге Destroy(current.southWall); Destroy(neighbor.northWall); } else if (dz == -1) { // Сосед на севере Destroy(current.northWall); Destroy(neighbor.southWall); } } void CreateMazeEntrance() { // Параметры двери float passageWidth = 2f; // Расчет индексов ячеек для прохода int entranceXIndex = 0; // Начало лабиринта по x int entranceZStart = 0; int passageCells = Mathf.CeilToInt(passageWidth / cellSize); // Создаем вход в лабиринт for (int i = 0; i < passageCells; i++) { int z = entranceZStart + i; if (z >= 0 && z < mazeHeight) { Destroy(grid[entranceXIndex, z].westWall); } } } void CreateMazeExit() { int exitXIndex = mazeWidth - 1; int exitZIndex = Random.Range(0, mazeHeight); Destroy(grid[exitXIndex, exitZIndex].eastWall); } } public class Cell { public bool visited = false; public GameObject northWall, southWall, eastWall, westWall, floor, upper, lightstick; }