Souljack/Assets/_Project/Scripts/LevelGenerating/WallsGenerator.cs

352 lines
14 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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> exitsInRoomType = new List<ExitsInRoomType>();
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 prevRoom,ExitsInRoomType exitForCor)
{
if (prevRoom == null || prevRoom.exits.Count == 0) return;
switch (exitForCor)
{
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<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);
}
}
break;
}
}
}
private bool IsRoomCanFit(Vector2 vector2, ExitsInRoomType exitForCor)
{
switch (exitForCor)
{
case ExitsInRoomType.XAxisP:
{
if ((lengthFloor - (vector2.x + lengthWallMin) >= 0)
&& (lengthFloor - (vector2.y + lengthWallMin / 2f) >= 0)
&& (vector2.y - lengthWallMin/ 2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.XAxisN:
{
if ((vector2.x - lengthWallMin >= 0)
&& (lengthFloor - (vector2.y + lengthWallMin / 2f) >= 0)
&& (vector2.y - lengthWallMin/ 2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.ZAxisP:
{
if ((lengthFloor - (vector2.y + lengthWallMin) >= 0)
&& (lengthFloor - (vector2.x + lengthWallMin / 2f) >= 0)
&& (vector2.x - lengthWallMin/ 2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.ZAxisN:
{
if ((vector2.y - lengthWallMin >= 0)
&& (lengthFloor - (vector2.x + lengthWallMin / 2f) >= 0)
&& (vector2.x - lengthWallMin/ 2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.Null:
default:
return false;
}
}
private bool IsRoomCanFit(Vector2 vector2,int lengthX,int lengthZ, ExitsInRoomType exitForCor)
{
switch (exitForCor)
{
case ExitsInRoomType.XAxisP:
{
if ((lengthFloor - (vector2.x + lengthX) >= 0)
&& (lengthFloor - (vector2.y + lengthZ / 2f) >= 0)
&& (vector2.y - lengthZ/2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.XAxisN:
{
if ((vector2.x - lengthX >= 0)
&& (lengthFloor - (vector2.y + lengthZ / 2f) >= 0)
&& (vector2.y - lengthZ/2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.ZAxisP:
{
if ((lengthFloor - (vector2.y + lengthZ) >= 0)
&& (lengthFloor - (vector2.x + lengthX / 2f) >= 0)
&& (vector2.x - lengthX/2f) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.ZAxisN:
{
if ((vector2.y - lengthZ >= 0)
&& (lengthFloor - (vector2.x + lengthX / 2f) >= 0)
&& (vector2.x - lengthX/2) >= 0)
{
return true;
}
return false;
}
case ExitsInRoomType.Null:
default:
return false;
}
}
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(room,room.exits.First());
}
}
}
}