-почти доделал базовую генерацию

This commit is contained in:
vladislove 2026-10-02 20:39:19 +03:00
parent 6f0520f9a0
commit 47f59350c8
4 changed files with 182 additions and 60 deletions

View File

@ -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

View File

@ -21,5 +21,10 @@ namespace _Project.Scripts.LevelGenerating
// return Rooms[Rooms.Count - 1];
return Rooms.Last();
}
public List<Room> GetRooms()
{
return Rooms;
}
}
}

View File

@ -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<ExitsInRoomType>();
}
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<ExitsInRoomType> exits)
public Room(Vector2 position, int width, int length, RoomType rt, bool isWallable, EntranceToRoomType entrance, List<ExitsInRoomType> 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; }

View File

@ -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,11 +130,11 @@ 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;
}
@ -121,46 +142,143 @@ namespace _Project.Scripts.LevelGenerating
{
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<ExitsInRoomType>();
// 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<ExitsInRoomType>();
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.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;
newRoom.exits = new List<ExitsInRoomType>();
if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2),
newRoom.Length, newRoom.Wigth, exitForCor))
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.Wigth,exitForCor);
CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor);
}
else
{
newRoom.isWallable = true;
EditRoomFoFitting(newRoom,exitForCor);
EditRoomFoFitting(newRoom); // Подгоняем размеры под границы карты
// Проверяем, вмещается ли хотя бы комната минимального размера после обрезки
if (newRoom.Length >= lengthWallMin && newRoom.Width >= lengthWallMin)
{
levelManager.AddRoom(newRoom);
CreateCorridor(newRoom.Position, newRoom.Length, newRoom.Width, exitForCor);
}
else
{
// Места не хватило даже для минимальной комнаты.
// Отменяем создание этой комнаты и завершаем ветку.
// При необходимости здесь можно удалить сгенерированный к ней коридор.
return;
}
}
break;
}
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());