From 47f59350c8ceed9deb921fa57c98e916cecfa090 Mon Sep 17 00:00:00 2001 From: vladislove Date: Fri, 2 Oct 2026 20:39:19 +0300 Subject: [PATCH] =?UTF-8?q?-=D0=BF=D0=BE=D1=87=D1=82=D0=B8=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2?= =?UTF-8?q?=D1=83=D1=8E=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scenes/Main.unity | 6 +- .../Scripts/LevelGenerating/LevelManager.cs | 7 +- .../_Project/Scripts/LevelGenerating/Room.cs | 20 +- .../Scripts/LevelGenerating/WallsGenerator.cs | 209 ++++++++++++++---- 4 files changed, 182 insertions(+), 60 deletions(-) diff --git a/Assets/Scenes/Main.unity b/Assets/Scenes/Main.unity index 7c5095c..3248794 100644 --- a/Assets/Scenes/Main.unity +++ b/Assets/Scenes/Main.unity @@ -13840,11 +13840,9 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 2197e0e0f0e04dbaa19b690f03f10300, type: 3} m_Name: m_EditorClassIdentifier: Assembly-CSharp::_Project.Scripts.LevelGenerating.WallsGenerator - roomCountMin: 0 - roomCountMax: 0 floorsCount: 10 - lengthWallMin: 0 - lengthWallMax: 0 + lengthWallMin: 5 + lengthWallMax: 25 lengthStartRoom: 10 lengthFloor: 100 corridorLength: 5 diff --git a/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs index c60c5be..be72271 100644 --- a/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs +++ b/Assets/_Project/Scripts/LevelGenerating/LevelManager.cs @@ -10,7 +10,7 @@ namespace _Project.Scripts.LevelGenerating { public static List Rooms = new List(); [SerializeField] private readonly int curFloor; - + public void AddRoom(Room room) { Rooms.Add(room); @@ -21,5 +21,10 @@ namespace _Project.Scripts.LevelGenerating // return Rooms[Rooms.Count - 1]; return Rooms.Last(); } + + public List GetRooms() + { + return Rooms; + } } } \ No newline at end of file diff --git a/Assets/_Project/Scripts/LevelGenerating/Room.cs b/Assets/_Project/Scripts/LevelGenerating/Room.cs index c1d8823..08b0908 100644 --- a/Assets/_Project/Scripts/LevelGenerating/Room.cs +++ b/Assets/_Project/Scripts/LevelGenerating/Room.cs @@ -5,10 +5,10 @@ namespace _Project.Scripts.LevelGenerating { public class Room { - public Room(Vector2 position, int wigth, int length, RoomType rt):this() + public Room(Vector2 position, int width, int length, RoomType rt):this() { Position = position; - Wigth = wigth; + Width = width; Length = length; this.rt = rt; } @@ -18,27 +18,27 @@ namespace _Project.Scripts.LevelGenerating exits = new List(); } - public Room(Vector2 position, int wigth, int length, RoomType rt, EntranceToRoomType entrance):this() + public Room(Vector2 position, int width, int length, RoomType rt, EntranceToRoomType entrance):this() { Position = position; - Wigth = wigth; + Width = width; Length = length; this.rt = rt; this.entrance = entrance; } - public Room(int wigth, int length, RoomType rt):this() + public Room(int width, int length, RoomType rt):this() { - Wigth = wigth; + Width = width; Length = length; this.rt = rt; } - public Room(Vector2 position, int wigth, int length, RoomType rt, bool isWallable, EntranceToRoomType entrance, List exits) + public Room(Vector2 position, int width, int length, RoomType rt, bool isWallable, EntranceToRoomType entrance, List exits) { Position = position; - Wigth = wigth; + Width = width; Length = length; this.rt = rt; this.entrance = entrance; @@ -46,8 +46,8 @@ namespace _Project.Scripts.LevelGenerating this.exits = exits; } - public int Wigth { get; set; } - public int Length { get; set; } + public int Width { get; set; }//width - по оси z + public int Length { get; set; }//length- по оси x public Vector2 Position; public RoomType rt { get; set; } public EntranceToRoomType entrance { get; set; } diff --git a/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs index 439eb99..babc45f 100644 --- a/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs +++ b/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs @@ -1,13 +1,15 @@ +using System; using System.Collections.Generic; using System.ComponentModel.Design.Serialization; using System.Linq; using UnityEngine; +using Random = UnityEngine.Random; + 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; @@ -24,15 +26,34 @@ namespace _Project.Scripts.LevelGenerating void Start() { levelManager = LevelManager.Instance; - CreateStartRoom(); + GenerateFloor(); } - void GenerateRooms() + void GenerateFloor() { - RoomCount = Random.Range(roomCountMin, roomCountMax); - LevelManager.Rooms.Add(new Room(Vector2.zero,lengthStartRoom, lengthStartRoom,RoomType.Start)); + CreateStartRoom(); + Instantiate(GameObjectA, new Vector3(0,-1,0), Quaternion.identity); + foreach (var room in levelManager.GetRooms()) + { + + float x = room.Position.x; + float z = room.Position.y; // В Vector2 ось Y отвечает за Z в 3D пространстве Unity + float length = room.Length; + float width = room.Width; + + // 4 угла комнаты: + // 1. Нижний левый (X, Z) + Instantiate(GameObjectB, new Vector3(x, 0, z), Quaternion.identity); + // 2. Нижний правый (X + Length, Z) + Instantiate(GameObjectB, new Vector3(x + length, 0, z), Quaternion.identity); + // 3. Верхний правый (X + Length, Z + Width) + Instantiate(GameObjectB, new Vector3(x + length, 0, z + width), Quaternion.identity); + // 4. Верхний левый (X, Z + Width) + Instantiate(GameObjectB, new Vector3(x, 0, z + width), Quaternion.identity); + } } + Room CreateCorridor(Vector2 posRoom, int Length, int Wigth, ExitsInRoomType exitType) { Vector2 corridorPos = Vector2.zero; @@ -109,58 +130,155 @@ namespace _Project.Scripts.LevelGenerating 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); + // // Визуализация коридора (расставляем маркеры по углам коридора для наглядности) + // 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 prevRoom,ExitsInRoomType exitForCor) { if (prevRoom == null || prevRoom.exits.Count == 0) return; + + // if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2), + // exitForCor)) + // { + // Room newRoom = GenerateRandomRoom(); + // newRoom.Position = new Vector2(); + // newRoom.rt = RoomType.Undefined; + // newRoom.entrance = EntranceToRoomType.XAxisP; + // newRoom.exits = new List(); + // if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2), + // newRoom.Length, newRoom.Width, exitForCor)) + // { + // newRoom.isWallable = false; + // levelManager.AddRoom(newRoom); + // CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor); + // } + // else + // { + // newRoom.isWallable = true; + // EditRoomFoFitting(newRoom); + // levelManager.AddRoom(newRoom); + // CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor); + // } + // } + + + Room newRoom = GenerateRandomRoom(); + newRoom.rt = RoomType.Undefined; + newRoom.exits = new List(); + + Vector2 newRoomPos = Vector2.zero; + // Вычисляем позицию новой комнаты и откуда в нее входит коридор switch (exitForCor) { + // Если вышли направо, новая комната слева получает вход (-X) case ExitsInRoomType.XAxisP: - { - if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2), - exitForCor)) - { - Room newRoom = GenerateRandomRoom(); - newRoom.Position = new Vector2(); - newRoom.rt = RoomType.Undefined; - newRoom.entrance = EntranceToRoomType.XAxisP; - newRoom.exits = new List(); - if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2), - newRoom.Length, newRoom.Wigth, exitForCor)) - { - newRoom.isWallable = false; - levelManager.AddRoom(newRoom); - CreateCorridor(newRoom.Position,newRoom.Length,newRoom.Wigth,exitForCor); - } - else - { - newRoom.isWallable = true; - EditRoomFoFitting(newRoom,exitForCor); - levelManager.AddRoom(newRoom); - } - } + newRoom.entrance = EntranceToRoomType.XAxisN; + newRoomPos = new Vector2( + prevRoom.Position.x + prevRoom.Length + corridorLength, // Сдвигаем на ширину пред. комнаты и коридор + prevRoom.Position.y + (prevRoom.Width / 2f) - (newRoom.Width / 2f) // Центрируем по оси Y (Z) + ); break; + + // Если вышли налево + case ExitsInRoomType.XAxisN: + newRoom.entrance = EntranceToRoomType.XAxisP; + newRoomPos = new Vector2( + prevRoom.Position.x - corridorLength - newRoom.Length, // Отступаем влево на коридор и ширину новой комнаты + prevRoom.Position.y + (prevRoom.Width / 2f) - (newRoom.Width / 2f) + ); + break; + + // Если вышли вверх (+Z/Y) + case ExitsInRoomType.ZAxisP: + newRoom.entrance = EntranceToRoomType.ZAxisN; + newRoomPos = new Vector2( + prevRoom.Position.x + (prevRoom.Length / 2f) - (newRoom.Length / 2f), // Центрируем по оси X + prevRoom.Position.y + prevRoom.Width + corridorLength + ); + break; + + // Если вышли вниз (-Z/Y) + case ExitsInRoomType.ZAxisN: + newRoom.entrance = EntranceToRoomType.ZAxisP; + newRoomPos = new Vector2( + prevRoom.Position.x + (prevRoom.Length / 2f) - (newRoom.Length / 2f), + prevRoom.Position.y - corridorLength - newRoom.Width + ); + break; + } + + // Устанавливаем просчитанную позицию + newRoom.Position = newRoomPos; + + // Проверяем, помещается ли комната с ее реальными размерами + if (IsRoomCanFit(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor)) + { + newRoom.isWallable = false; + levelManager.AddRoom(newRoom); + CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor); + } + else + { + newRoom.isWallable = true; + EditRoomFoFitting(newRoom); // Подгоняем размеры под границы карты + + // Проверяем, вмещается ли хотя бы комната минимального размера после обрезки + if (newRoom.Length >= lengthWallMin && newRoom.Width >= lengthWallMin) + { + levelManager.AddRoom(newRoom); + CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor); + } + else + { + // Места не хватило даже для минимальной комнаты. + // Отменяем создание этой комнаты и завершаем ветку. + // При необходимости здесь можно удалить сгенерированный к ней коридор. + return; } } + if (exitForCor != ExitsInRoomType.XAxisN) TryPlaceRoom(newRoom, ExitsInRoomType.XAxisP); + + // 2. Влево (-X): идем, только если TryPlaceRoomНЕ слеа (XAxisP) + if (exitForCor != ExitsInRoomType.XAxisP) TryPlaceRoom(newRoom, ExitsInRoomType.XAxisN); + + // 3. Вверх/Вперед (+Z): идем, только TryPlaceRoomпришли НЕ верху (ZAxisN) + if (exitForCor != ExitsInRoomType.ZAxisN) TryPlaceRoom(newRoom, ExitsInRoomType.ZAxisP); + + // 4. Вниз/Назад (-Z): идем, только если TryPlaceRoomишли НЕ сниу (ZAxisP) + if (exitForCor != ExitsInRoomType.ZAxisP) TryPlaceRoom(newRoom, ExitsInRoomType.ZAxisN); + } - } + private void EditRoomFoFitting(Room room) { - if (room.Position.x + room.Length - lengthFloor <= 0) + if (lengthFloor - room.Position.x + room.Length <= 0) { - + room.Length = lengthFloor - Convert.ToInt32(room.Position.x); } + if (lengthFloor - room.Position.y + room.Width <= 0) + { + room.Width = lengthFloor - Convert.ToInt32(room.Position.y); + } + + if (room.Position.x < 0) + { + room.Position.x = 0; + } + + if (room.Position.y < 0) + { + room.Position.y = 0; + } + } @@ -276,7 +394,7 @@ namespace _Project.Scripts.LevelGenerating int b = Random.Range(lengthWallMin, lengthWallMax); Room room = new Room(); room.Length = a; - room.Wigth = b; + room.Width = b; return room; } @@ -346,15 +464,16 @@ namespace _Project.Scripts.LevelGenerating 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); + // 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()); + Room firstCorridor = CreateCorridor(new Vector2(xR, zR), lengthStartRoom, + lengthStartRoom, room.exits.First()); if (firstCorridor != null) { TryPlaceRoom(room,room.exits.First());