-почти доделал базовую генерацию
This commit is contained in:
parent
6f0520f9a0
commit
47f59350c8
@ -13840,11 +13840,9 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 2197e0e0f0e04dbaa19b690f03f10300, type: 3}
|
m_Script: {fileID: 11500000, guid: 2197e0e0f0e04dbaa19b690f03f10300, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier: Assembly-CSharp::_Project.Scripts.LevelGenerating.WallsGenerator
|
m_EditorClassIdentifier: Assembly-CSharp::_Project.Scripts.LevelGenerating.WallsGenerator
|
||||||
roomCountMin: 0
|
|
||||||
roomCountMax: 0
|
|
||||||
floorsCount: 10
|
floorsCount: 10
|
||||||
lengthWallMin: 0
|
lengthWallMin: 5
|
||||||
lengthWallMax: 0
|
lengthWallMax: 25
|
||||||
lengthStartRoom: 10
|
lengthStartRoom: 10
|
||||||
lengthFloor: 100
|
lengthFloor: 100
|
||||||
corridorLength: 5
|
corridorLength: 5
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
{
|
{
|
||||||
public static List<Room> Rooms = new List<Room>();
|
public static List<Room> Rooms = new List<Room>();
|
||||||
[SerializeField] private readonly int curFloor;
|
[SerializeField] private readonly int curFloor;
|
||||||
|
|
||||||
public void AddRoom(Room room)
|
public void AddRoom(Room room)
|
||||||
{
|
{
|
||||||
Rooms.Add(room);
|
Rooms.Add(room);
|
||||||
@ -21,5 +21,10 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
// return Rooms[Rooms.Count - 1];
|
// return Rooms[Rooms.Count - 1];
|
||||||
return Rooms.Last();
|
return Rooms.Last();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Room> GetRooms()
|
||||||
|
{
|
||||||
|
return Rooms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,10 +5,10 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
{
|
{
|
||||||
public class Room
|
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;
|
Position = position;
|
||||||
Wigth = wigth;
|
Width = width;
|
||||||
Length = length;
|
Length = length;
|
||||||
this.rt = rt;
|
this.rt = rt;
|
||||||
}
|
}
|
||||||
@ -18,27 +18,27 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
exits = new List<ExitsInRoomType>();
|
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;
|
Position = position;
|
||||||
Wigth = wigth;
|
Width = width;
|
||||||
Length = length;
|
Length = length;
|
||||||
this.rt = rt;
|
this.rt = rt;
|
||||||
this.entrance = entrance;
|
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;
|
Length = length;
|
||||||
this.rt = rt;
|
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;
|
Position = position;
|
||||||
Wigth = wigth;
|
Width = width;
|
||||||
Length = length;
|
Length = length;
|
||||||
this.rt = rt;
|
this.rt = rt;
|
||||||
this.entrance = entrance;
|
this.entrance = entrance;
|
||||||
@ -46,8 +46,8 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
this.exits = exits;
|
this.exits = exits;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Wigth { get; set; }
|
public int Width { get; set; }//width - по оси z
|
||||||
public int Length { get; set; }
|
public int Length { get; set; }//length- по оси x
|
||||||
public Vector2 Position;
|
public Vector2 Position;
|
||||||
public RoomType rt { get; set; }
|
public RoomType rt { get; set; }
|
||||||
public EntranceToRoomType entrance { get; set; }
|
public EntranceToRoomType entrance { get; set; }
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Design.Serialization;
|
using System.ComponentModel.Design.Serialization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
namespace _Project.Scripts.LevelGenerating
|
namespace _Project.Scripts.LevelGenerating
|
||||||
{
|
{
|
||||||
public class WallsGenerator : MonoBehaviour
|
public class WallsGenerator : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private int roomCountMin;
|
|
||||||
[SerializeField] private int roomCountMax;
|
|
||||||
[SerializeField] private int floorsCount;
|
[SerializeField] private int floorsCount;
|
||||||
[SerializeField] private int lengthWallMin;
|
[SerializeField] private int lengthWallMin;
|
||||||
[SerializeField] private int lengthWallMax;
|
[SerializeField] private int lengthWallMax;
|
||||||
@ -24,15 +26,34 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
void Start()
|
void Start()
|
||||||
{
|
{
|
||||||
levelManager = LevelManager.Instance;
|
levelManager = LevelManager.Instance;
|
||||||
CreateStartRoom();
|
GenerateFloor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateRooms()
|
void GenerateFloor()
|
||||||
{
|
{
|
||||||
RoomCount = Random.Range(roomCountMin, roomCountMax);
|
CreateStartRoom();
|
||||||
LevelManager.Rooms.Add(new Room(Vector2.zero,lengthStartRoom, lengthStartRoom,RoomType.Start));
|
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)
|
Room CreateCorridor(Vector2 posRoom, int Length, int Wigth, ExitsInRoomType exitType)
|
||||||
{
|
{
|
||||||
Vector2 corridorPos = Vector2.zero;
|
Vector2 corridorPos = Vector2.zero;
|
||||||
@ -109,58 +130,155 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
|
|
||||||
LevelManager.Rooms.Add(corridor);
|
LevelManager.Rooms.Add(corridor);
|
||||||
|
|
||||||
// Визуализация коридора (расставляем маркеры по углам коридора для наглядности)
|
// // Визуализация коридора (расставляем маркеры по углам коридора для наглядности)
|
||||||
Instantiate(GameObjectB, new Vector3(corridorPos.x, 0, corridorPos.y), 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), Quaternion.identity);
|
||||||
Instantiate(GameObjectB, new Vector3(corridorPos.x + cLength, 0, corridorPos.y + cWidth), 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 + cWidth), Quaternion.identity);
|
||||||
return corridor;
|
return corridor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TryPlaceRoom(Room prevRoom,ExitsInRoomType exitForCor)
|
void TryPlaceRoom(Room prevRoom,ExitsInRoomType exitForCor)
|
||||||
{
|
{
|
||||||
if (prevRoom == null || prevRoom.exits.Count == 0) return;
|
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)
|
switch (exitForCor)
|
||||||
{
|
{
|
||||||
|
// Если вышли направо, новая комната слева получает вход (-X)
|
||||||
case ExitsInRoomType.XAxisP:
|
case ExitsInRoomType.XAxisP:
|
||||||
{
|
newRoom.entrance = EntranceToRoomType.XAxisN;
|
||||||
if (IsRoomCanFit(new Vector2(prevRoom.Position.x + prevRoom.Length, prevRoom.Position.y / 2),
|
newRoomPos = new Vector2(
|
||||||
exitForCor))
|
prevRoom.Position.x + prevRoom.Length + corridorLength, // Сдвигаем на ширину пред. комнаты и коридор
|
||||||
{
|
prevRoom.Position.y + (prevRoom.Width / 2f) - (newRoom.Width / 2f) // Центрируем по оси Y (Z)
|
||||||
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.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
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)
|
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);
|
int b = Random.Range(lengthWallMin, lengthWallMax);
|
||||||
Room room = new Room();
|
Room room = new Room();
|
||||||
room.Length = a;
|
room.Length = a;
|
||||||
room.Wigth = b;
|
room.Width = b;
|
||||||
return room;
|
return room;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,15 +464,16 @@ namespace _Project.Scripts.LevelGenerating
|
|||||||
|
|
||||||
room.entrance = EntranceToRoomType.Null;
|
room.entrance = EntranceToRoomType.Null;
|
||||||
LevelManager.Rooms.Add(room);
|
LevelManager.Rooms.Add(room);
|
||||||
Instantiate(GameObjectA, new Vector3(0,-1,0), 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,0,zR), Quaternion.identity);
|
||||||
Instantiate(GameObjectB, new Vector3(xR+lengthStartRoom,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+lengthStartRoom,0,zR+lengthStartRoom), Quaternion.identity);
|
||||||
Instantiate(GameObjectB, new Vector3(xR,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());
|
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)
|
if (firstCorridor != null)
|
||||||
{
|
{
|
||||||
TryPlaceRoom(room,room.exits.First());
|
TryPlaceRoom(room,room.exits.First());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user