diff --git a/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs new file mode 100644 index 0000000..5288583 --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using _Project.Scripts.Utilities; +using NUnit.Framework; +using UnityEngine; + +namespace _Project.Scripts.LevelGenerating +{ + public class LevelManager : MonoSingleton + { + public static List Rooms = new List(); + [SerializeField] private readonly int curFloor; + + void AddRoom(ref Room room) + { + Rooms.Add(room); + } + } +} \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs.meta b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs.meta new file mode 100644 index 0000000..fd21e49 --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4998e3ff3051468998a4d4d904be1956 +timeCreated: 1790353372 \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs b/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs deleted file mode 100644 index 00c4a41..0000000 --- a/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System.Collections.Generic; -using UnityEngine; - -public class ProceduralLevelGenerator : MonoBehaviour -{ - [Header("Настройки генерации")] - public int numberOfRooms = 8; - public Vector2Int minRoomSize = new Vector2Int(5, 5); - public Vector2Int maxRoomSize = new Vector2Int(12, 12); - public float tileSize = 2f; - public float wallHeight = 8f; // Ты указал высоту 8 - - [Header("Префабы строительных блоков")] - public GameObject floorPrefab; - public GameObject wallPrefab; - - // Структура клетки - private class Cell - { - public int roomID; - public int floorHeight; - } - - // Структура для прохода (двери) - private class Passage - { - public Vector2Int cellA; // Клетка из одной комнаты - public Vector2Int cellB; // Клетка из другой комнаты - } - - private Dictionary levelMap = new Dictionary(); - private List rooms = new List(); - - // Список всех прорубленных проходов - private List passages = new List(); - - void Start() - { - GenerateLayout(); - ApplyVerticality(); - BuildMesh(); - } - - void GenerateLayout() - { - // --- ШАГ 1: Стартовая комната (10x10) --- - int startWidth = 10; - int startHeight = 10; - int startX = -startWidth / 2; - int startY = -startHeight / 2; - - RectInt startRoom = new RectInt(startX, startY, startWidth, startHeight); - rooms.Add(startRoom); - SaveRoomToMap(startRoom, 0); - - // --- ШАГ 2: Первая комната с врагами --- - int firstEnemyWidth = Random.Range(minRoomSize.x, maxRoomSize.x); - int firstEnemyHeight = Random.Range(minRoomSize.y, maxRoomSize.y); - - int firstEnemyX = startRoom.x + Random.Range(-firstEnemyWidth / 2, startRoom.width - firstEnemyWidth / 2); - int firstEnemyY = startRoom.yMax; - - RectInt firstEnemyRoom = new RectInt(firstEnemyX, firstEnemyY, firstEnemyWidth, firstEnemyHeight); - rooms.Add(firstEnemyRoom); - SaveRoomToMap(firstEnemyRoom, 1); - - // ПРОРУБАЕМ ПРОХОД между стартовой и первой вражеской комнатой - CreatePassage(startRoom, firstEnemyRoom); - - // --- ШАГ 3: Остальные комнаты --- - for (int i = 2; i < numberOfRooms; i++) - { - bool roomPlaced = false; - int attempts = 0; - - while (!roomPlaced && attempts < 50) - { - attempts++; - - // Выбираем случайную комнату (кроме стартовой) - int baseRoomIndex = Random.Range(1, rooms.Count); - RectInt baseRoom = rooms[baseRoomIndex]; - - int newWidth = Random.Range(minRoomSize.x, maxRoomSize.x); - int newHeight = Random.Range(minRoomSize.y, maxRoomSize.y); - - int side = Random.Range(0, 4); - RectInt newRoom = new RectInt(); - - if (side == 0) // Север - newRoom = new RectInt(baseRoom.x + Random.Range(-newWidth/2, baseRoom.width - newWidth/2), baseRoom.yMax, newWidth, newHeight); - else if (side == 1) // Юг - newRoom = new RectInt(baseRoom.x + Random.Range(-newWidth/2, baseRoom.width - newWidth/2), baseRoom.yMin - newHeight, newWidth, newHeight); - else if (side == 2) // Восток - newRoom = new RectInt(baseRoom.xMax, baseRoom.y + Random.Range(-newHeight/2, baseRoom.height - newHeight/2), newWidth, newHeight); - else if (side == 3) // Запад - newRoom = new RectInt(baseRoom.xMin - newWidth, baseRoom.y + Random.Range(-newHeight/2, baseRoom.height - newHeight/2), newWidth, newHeight); - - if (!CheckOverlap(newRoom)) - { - rooms.Add(newRoom); - SaveRoomToMap(newRoom, i); - - // ПРОРУБАЕМ ПРОХОД между базовой комнатой и новой - CreatePassage(baseRoom, newRoom); - - roomPlaced = true; - } - } - } - } - - // Выбирает одну случайную общую стену между двумя комнатами и делает там проход - void CreatePassage(RectInt room1, RectInt room2) - { - List potentialPassages = new List(); - - // Проходим по всем клеткам первой комнаты - for (int x = room1.xMin; x < room1.xMax; x++) - { - for (int y = room1.yMin; y < room1.yMax; y++) - { - Vector2Int cellA = new Vector2Int(x, y); - Vector2Int[] dirs = { Vector2Int.up, Vector2Int.down, Vector2Int.left, Vector2Int.right }; - - // Проверяем соседей - foreach (var dir in dirs) - { - Vector2Int cellB = cellA + dir; - // Если соседняя клетка находится во второй комнате — это потенциальная дверь! - if (cellB.x >= room2.xMin && cellB.x < room2.xMax && - cellB.y >= room2.yMin && cellB.y < room2.yMax) - { - potentialPassages.Add(new Vector2Int[] { cellA, cellB }); - } - } - } - } - - // Если нашли точки соприкосновения, берем ОДНУ случайную и делаем там проход - if (potentialPassages.Count > 0) - { - Vector2Int[] chosen = potentialPassages[Random.Range(0, potentialPassages.Count)]; - passages.Add(new Passage { cellA = chosen[0], cellB = chosen[1] }); - } - } - - void ApplyVerticality() - { - for (int i = 1; i < rooms.Count; i++) - { - RectInt room = rooms[i]; - - if (Random.value > 0.5f) - { - int platformWidth = room.width / 2; - int platformHeight = room.height / 2; - int offsetX = Random.Range(1, room.width - platformWidth - 1); - int offsetY = Random.Range(1, room.height - platformHeight - 1); - - for (int x = 0; x < platformWidth; x++) - { - for (int y = 0; y < platformHeight; y++) - { - Vector2Int pos = new Vector2Int(room.x + offsetX + x, room.y + offsetY + y); - if (levelMap.ContainsKey(pos)) - { - levelMap[pos].floorHeight = 1; - } - } - } - } - } - } - - void BuildMesh() - { - Vector2Int[] directions = { Vector2Int.up, Vector2Int.down, Vector2Int.right, Vector2Int.left }; - float[] wallRotations = { 0f, 180f, 90f, -90f }; - - foreach (var kvp in levelMap) - { - Vector2Int pos = kvp.Key; - Cell cell = kvp.Value; - - // Вычисляем высоту (чтобы балконы были логичной высоты, умножаем на половину высоты стены) - float worldHeight = cell.floorHeight * (wallHeight * 0.5f); - - Vector3 floorPos = new Vector3(pos.x * tileSize, worldHeight, pos.y * tileSize); - GameObject floor = Instantiate(floorPrefab, floorPos, Quaternion.identity, this.transform); - floor.name = $"Floor_{pos.x}_{pos.y}"; - - for (int i = 0; i < 4; i++) - { - Vector2Int neighborPos = pos + directions[i]; - bool needsWall = false; - - if (!levelMap.ContainsKey(neighborPos)) - { - // Соседа нет -> глухая внешняя стена - needsWall = true; - } - else - { - Cell neighborCell = levelMap[neighborPos]; - - if (neighborCell.roomID != cell.roomID) - { - // Это граница двух комнат. Проверяем, есть ли здесь проход. - if (IsPassage(pos, neighborPos)) - { - needsWall = false; // ПРОПУСКАЕМ СТЕНУ (оставляем дыру для двери) - } - else - { - needsWall = true; // Ставим стену - } - } - else if (neighborCell.floorHeight > cell.floorHeight) - { - // Сосед выше, нужна стена-ступенька внутри комнаты - needsWall = true; - } - } - - if (needsWall) - { - Vector3 wallPos = floorPos + new Vector3(directions[i].x * (tileSize / 2), wallHeight / 2, directions[i].y * (tileSize / 2)); - GameObject wall = Instantiate(wallPrefab, wallPos, Quaternion.Euler(0, wallRotations[i], 0), this.transform); - wall.name = $"Wall_{pos.x}_{pos.y}_{i}"; - } - } - } - } - - // Проверяет, является ли граница между двумя клетками проходом - bool IsPassage(Vector2Int a, Vector2Int b) - { - foreach (var p in passages) - { - if ((p.cellA == a && p.cellB == b) || (p.cellA == b && p.cellB == a)) - { - return true; - } - } - return false; - } - - void SaveRoomToMap(RectInt room, int id) - { - for (int x = room.xMin; x < room.xMax; x++) - { - for (int y = room.yMin; y < room.yMax; y++) - { - levelMap[new Vector2Int(x, y)] = new Cell { roomID = id, floorHeight = 0 }; - } - } - } - - bool CheckOverlap(RectInt newRoom) - { - foreach (RectInt room in rooms) - { - if (newRoom.xMin < room.xMax && newRoom.xMax > room.xMin && - newRoom.yMin < room.yMax && newRoom.yMax > room.yMin) - { - return true; - } - } - return false; - } -} \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs.meta b/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs.meta deleted file mode 100644 index f101f9b..0000000 --- a/Assets/_Project/Scripts/LevelGenerating/ProceduralLevelGenerator.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 05c6005aaf0a4e4ab66fd5a02bcde0e1 -timeCreated: 1790254468 \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/Room.cs b/Assets/_Project/Scripts/LevelGenerating/Room.cs new file mode 100644 index 0000000..8818925 --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/Room.cs @@ -0,0 +1,25 @@ +using UnityEngine; + +namespace _Project.Scripts.LevelGenerating +{ + public class Room + { + public Room(Vector2 position, int wigth, int length, RoomType rt) + { + Position = position; + Wigth = wigth; + Length = length; + this.rt = rt; + } + + public Room() + { + } + + public int Wigth { get; set; } + public int Length { get; set; } + public Vector2 Position; + public RoomType rt { get; set; } + } + +} \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/Room.cs.meta b/Assets/_Project/Scripts/LevelGenerating/Room.cs.meta new file mode 100644 index 0000000..41423a2 --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/Room.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: af744d57618340969ba8690e9dc177ff +timeCreated: 1790352651 \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/RoomType.cs b/Assets/_Project/Scripts/LevelGenerating/RoomType.cs new file mode 100644 index 0000000..b3b7337 --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/RoomType.cs @@ -0,0 +1,15 @@ +namespace _Project.Scripts.LevelGenerating +{ + public enum RoomType + { + Start, + Lift, + Laboratory, + Boss, + Office, + Penthouse, + Storage, + SwitchboardRoom, + BoilerRoom + } +} \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/RoomType.cs.meta b/Assets/_Project/Scripts/LevelGenerating/RoomType.cs.meta new file mode 100644 index 0000000..eed385c --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/RoomType.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2c424d1e4c364d2f961f8d2fdd959c51 +timeCreated: 1790352839 \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs new file mode 100644 index 0000000..4dcbe9e --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs @@ -0,0 +1,44 @@ +using UnityEngine; +namespace _Project.Scripts.LevelGenerating +{ + public class WallsGenerator : MonoBehaviour + { + [SerializeField] private int roomCountMin; + [SerializeField] private int roomCountMax; + [SerializeField] private int floorsCount; + [SerializeField] private int lengthWallMin; + [SerializeField] private int lengthWallMax; + [SerializeField] private int lengthStartRoomA; + [SerializeField] private int lengthStartRoomB; + [SerializeField] private int lengthFloorMax; + [SerializeField] private int lengthFloorMin; + + private int RoomCount; + private LevelManager levelManager; + + void Start() + { + levelManager = LevelManager.Instance; + } + + void GenerateRooms() + { + RoomCount = Random.Range(roomCountMin, roomCountMax); + LevelManager.Rooms.Add(new Room(Vector2.zero,lengthStartRoomA, lengthStartRoomB,RoomType.Start)); + + } + + + + void CreateRoom() + { + int a = Random.Range(lengthWallMin, lengthWallMax); + int b = Random.Range(lengthWallMin, lengthWallMax); + Room room = new Room(); + room.Length = a; + room.Wigth = b; + } + + + } +} \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs.meta b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs.meta new file mode 100644 index 0000000..d9a3c1e --- /dev/null +++ b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2197e0e0f0e04dbaa19b690f03f10300 +timeCreated: 1790353086 \ No newline at end of file