using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Linq; 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 lengthStartRoom; [SerializeField] private int lengthFloor; [SerializeField] private int corridorLength; [SerializeField] private int corridorWigth; [SerializeField] private GameObject GameObjectA; [SerializeField] private GameObject GameObjectB; private int RoomCount; private LevelManager levelManager; void Start() { levelManager = LevelManager.Instance; CreateStartRoom(); } void GenerateRooms() { RoomCount = Random.Range(roomCountMin, roomCountMax); LevelManager.Rooms.Add(new Room(Vector2.zero,lengthStartRoom, lengthStartRoom,RoomType.Start)); } Room CreateCorridor(Vector2 posRoom, int Length, int Wigth, ExitsInRoomType exitType) { Vector2 corridorPos = Vector2.zero; int cLength = 0; int cWidth = 0; EntranceToRoomType entranceToRoomType = EntranceToRoomType.Null; List exitsInRoomType = new List(); switch (exitType) { // Выход направо (+X) case ExitsInRoomType.XAxisP: // Начинается у правой стены комнаты (posRoom.x + Length) // Центрируем коридор по высоте/оси Z: смещаем на половину разницы ширин exitsInRoomType.Add (ExitsInRoomType.XAxisP); entranceToRoomType = EntranceToRoomType.XAxisN; corridorPos = new Vector2( posRoom.x + Length, posRoom.y + (Wigth - corridorWigth) / 2f ); cLength = corridorLength; cWidth = corridorWigth; break; // Выход налево (-X) case ExitsInRoomType.XAxisN: // Начинается слева от комнаты, отступая на длину коридора exitsInRoomType .Add (ExitsInRoomType.XAxisN); entranceToRoomType = EntranceToRoomType.XAxisP; corridorPos = new Vector2( posRoom.x - corridorLength, posRoom.y + (Wigth - corridorWigth) / 2f ); cLength = corridorLength; cWidth = corridorWigth; break; // Выход вперед/вверх (+Z / в Vector2 это Y) case ExitsInRoomType.ZAxisP: entranceToRoomType = EntranceToRoomType.ZAxisN; exitsInRoomType.Add (ExitsInRoomType.ZAxisP); // Начинается у верхней стены комнаты (posRoom.y + Wigth) // Центрируем коридор по горизонтали/оси X: corridorPos = new Vector2( posRoom.x + (Length - corridorWigth) / 2f, posRoom.y + Wigth ); // По оси X коридор узкий, по оси Z — длинный: cLength = corridorWigth; cWidth = corridorLength; break; // Выход назад/вниз (-Z / в Vector2 это Y) case ExitsInRoomType.ZAxisN: entranceToRoomType = EntranceToRoomType.ZAxisP; exitsInRoomType.Add (ExitsInRoomType.ZAxisN); // Начинается ниже комнаты, отступая на длину коридора corridorPos = new Vector2( posRoom.x + (Length - corridorWigth) / 2f, posRoom.y - corridorLength ); cLength = corridorWigth; cWidth = corridorLength; break; } // Создаем коридор как отдельную комнату Room corridor = new Room(corridorPos, cLength, cWidth, RoomType.Corridor,false, EntranceToRoomType.Null,exitsInRoomType); LevelManager.Rooms.Add(corridor); // Визуализация коридора (расставляем маркеры по углам коридора для наглядности) Instantiate(GameObjectB, new Vector3(corridorPos.x, 0, corridorPos.y), Quaternion.identity); Instantiate(GameObjectB, new Vector3(corridorPos.x + cLength, 0, corridorPos.y), Quaternion.identity); Instantiate(GameObjectB, new Vector3(corridorPos.x + cLength, 0, corridorPos.y + cWidth), Quaternion.identity); Instantiate(GameObjectB, new Vector3(corridorPos.x, 0, corridorPos.y + cWidth), Quaternion.identity); return corridor; } void TryPlaceRoom(Room corridor) { // Room lastCorridor = LevelManager.Instance.GetLastRoom(); if (corridor != null && corridor.exits.Count == 1) { switch (corridor.exits.Last()) { case ExitsInRoomType.XAxisP: { if ((lengthFloor - (corridor.Position.x + corridorLength + lengthWallMin) > 0) && (lengthFloor - (corridor.Position.y + corridorWigth + lengthWallMin) > 0)) { Room newRoom = GenerateRandomRoom(); if() } break; } } } } Room GenerateRandomRoom() { int a = Random.Range(lengthWallMin, lengthWallMax); int b = Random.Range(lengthWallMin, lengthWallMax); Room room = new Room(); room.Length = a; room.Wigth = b; return room; } void CreateStartRoom() { float randValue = Random.value; int xR, zR; Vector2Int posStartRoom = new Vector2Int(); Room room = new Room( lengthStartRoom, lengthStartRoom, RoomType.Start); if (randValue < 0.25f) //1 квадрант { xR = Random.Range(0,lengthFloor/2-lengthStartRoom); if (xR + lengthStartRoom <= lengthFloor / 4) { room.exits.Add(ExitsInRoomType.XAxisP); zR = Random.Range(0, lengthFloor/2-lengthStartRoom); } else { room.exits.Add(ExitsInRoomType.ZAxisP); zR = Random.Range(0, lengthFloor/4-lengthStartRoom); } } else if (randValue < 0.5f) // 2 квадрант { xR = Random.Range(lengthFloor/2, lengthFloor-lengthStartRoom);//от половины до конца if (xR + lengthStartRoom <= lengthFloor * 3/4) { room.exits.Add(ExitsInRoomType.ZAxisP); zR = Random.Range(0, lengthFloor/4-lengthStartRoom); } else { room.exits.Add(ExitsInRoomType.XAxisN); zR = Random.Range(0, lengthFloor/2-lengthStartRoom); } } else if (randValue < 0.75f) { xR = Random.Range(lengthFloor / 2, lengthFloor - lengthStartRoom); if (xR + lengthStartRoom <= lengthFloor * 3 / 4) { room.exits.Add(ExitsInRoomType.ZAxisN); zR = Random.Range(lengthFloor * 3 / 4, lengthFloor - lengthStartRoom); } else { room.exits.Add(ExitsInRoomType.XAxisN); zR = Random.Range(lengthFloor / 2, lengthFloor - lengthStartRoom); } } else { xR = Random.Range(0, lengthFloor / 2 - lengthStartRoom); if (xR + lengthStartRoom <= lengthFloor / 4) { room.exits.Add(ExitsInRoomType.XAxisP); zR = Random.Range(lengthFloor / 2, lengthFloor - lengthStartRoom); } else { room.exits.Add(ExitsInRoomType.ZAxisN); zR = Random.Range(lengthFloor * 3 / 4, lengthFloor - lengthStartRoom); } } room.entrance = EntranceToRoomType.Null; LevelManager.Rooms.Add(room); Instantiate(GameObjectA, new Vector3(0,-1,0), Quaternion.identity); Instantiate(GameObjectB, new Vector3(xR,0,zR), Quaternion.identity); Instantiate(GameObjectB, new Vector3(xR+lengthStartRoom,0,zR), Quaternion.identity); Instantiate(GameObjectB, new Vector3(xR+lengthStartRoom,0,zR+lengthStartRoom), Quaternion.identity); Instantiate(GameObjectB, new Vector3(xR,0,zR+lengthStartRoom), Quaternion.identity); CreateCorridor(new Vector2Int(xR, zR),lengthStartRoom,lengthStartRoom,room.exits.First()); Room firstCorridor = CreateCorridor(new Vector2(xR, zR), lengthStartRoom, lengthStartRoom, room.exits.First()); if (firstCorridor != null) { TryPlaceRoom(firstCorridor); } } } }