200 lines
6.8 KiB
C#
200 lines
6.8 KiB
C#
using System.Collections.Generic;
|
|
using Cysharp.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace Code.Generator
|
|
{
|
|
public class RoomGenerator : MonoBehaviour
|
|
{
|
|
[SerializeField] private GeneratorConfig generatorConfig;
|
|
|
|
private RoomGeneratorFactory _factory;
|
|
|
|
private float _timer;
|
|
private List<int> _roomIndexesStack;
|
|
private List<Room> _spawnedRooms;
|
|
|
|
private async void Awake()
|
|
{
|
|
_factory = new RoomGeneratorFactory(generatorConfig);
|
|
_spawnedRooms = new List<Room>();
|
|
_roomIndexesStack = new List<int>();
|
|
|
|
_timer = Random.Range(60, 120f);
|
|
Debug.LogWarning($"КОТЛЫ ГЕНЕРАЛЬСКИЕ{_timer}");
|
|
|
|
await _factory.PreloadRooms();
|
|
|
|
CreateRoomsStack();
|
|
await GenerateRoomsAsync();
|
|
}
|
|
|
|
private void CreateRoomsStack()
|
|
{
|
|
_roomIndexesStack.Clear();
|
|
var remainingTime = _timer;
|
|
float ladderTimer = 0f;
|
|
int totalRooms = generatorConfig.roomAssetReferences.Length;
|
|
List<int> availableIndexes = new List<int>();
|
|
for (int i = 0; i < totalRooms; i++)
|
|
availableIndexes.Add(i);
|
|
|
|
int saveIndex = FindRoomIndexByType(RoomType.Save);
|
|
if (saveIndex != -1)
|
|
{
|
|
var prefab = _factory.GetCachedPrefab(saveIndex);
|
|
if (prefab != null)
|
|
{
|
|
Room saveRoom = prefab.GetComponent<Room>();
|
|
if (saveRoom != null)
|
|
{
|
|
_roomIndexesStack.Add(saveIndex);
|
|
availableIndexes.Remove(saveIndex);
|
|
|
|
Debug.Log($"Первая комната: {saveRoom.name}");
|
|
}
|
|
}
|
|
}
|
|
|
|
while (remainingTime > 0 && availableIndexes.Count > 0)
|
|
{
|
|
int randomIndex = Random.Range(0, availableIndexes.Count);
|
|
int chosenOne = availableIndexes[randomIndex];
|
|
|
|
var prefab = _factory.GetCachedPrefab(chosenOne);
|
|
if (prefab == null)
|
|
continue;
|
|
|
|
Room room = prefab.GetComponent<Room>();
|
|
if (room == null)
|
|
continue;
|
|
|
|
switch (room.RoomType)
|
|
{
|
|
case RoomType.Save or RoomType.PickUp:
|
|
availableIndexes.RemoveAt(randomIndex);
|
|
continue;
|
|
|
|
case RoomType.Basic:
|
|
float currentRoomTime = room.RoomTimer;
|
|
if (remainingTime >= currentRoomTime && ladderTimer < 30f)
|
|
{
|
|
_roomIndexesStack.Add(chosenOne);
|
|
remainingTime -= currentRoomTime;
|
|
ladderTimer += currentRoomTime;
|
|
Debug.Log($"комната {room.name} время {currentRoomTime} осталось: {remainingTime}");
|
|
}
|
|
availableIndexes.RemoveAt(randomIndex);
|
|
break;
|
|
|
|
case RoomType.Ladder:
|
|
if (ladderTimer >= 30f)
|
|
{
|
|
_roomIndexesStack.Add(chosenOne);
|
|
ladderTimer = 0f;
|
|
|
|
availableIndexes.RemoveAt(randomIndex);
|
|
Debug.Log($"Лестница ура {room.name}");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Debug.Log($"тип комнаты {room.RoomType}");
|
|
availableIndexes.RemoveAt(randomIndex);
|
|
break;
|
|
}
|
|
}
|
|
|
|
AddPickupRoom();
|
|
Debug.Log($"стек комнат: {_roomIndexesStack.Count}");
|
|
}
|
|
|
|
private async UniTask GenerateRoomsAsync()
|
|
{
|
|
for (int i = 0; i < _roomIndexesStack.Count; i++)
|
|
{
|
|
int index = _roomIndexesStack[i];
|
|
Room room = await _factory.CreateRoomByIndex(index);
|
|
|
|
if (i == 0)
|
|
{
|
|
room.transform.position = Vector3.zero;
|
|
room.transform.rotation = Quaternion.identity;
|
|
}
|
|
else
|
|
{
|
|
Room previousRoom = _spawnedRooms[i - 1];
|
|
PlaceRoom(room, previousRoom);
|
|
}
|
|
|
|
_spawnedRooms.Add(room);
|
|
}
|
|
}
|
|
|
|
private int FindRoomIndexByType(RoomType neededType)
|
|
{
|
|
int totalRooms = generatorConfig.roomAssetReferences.Length;
|
|
for (int i = 0; i < totalRooms; i++)
|
|
{
|
|
var prefab = _factory.GetCachedPrefab(i);
|
|
if (prefab == null)
|
|
continue;
|
|
|
|
Room room = prefab.GetComponent<Room>();
|
|
if (room == null)
|
|
continue;
|
|
|
|
if (room.RoomType == neededType)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
private void AddPickupRoom()
|
|
{
|
|
int pickupIndex = FindRoomIndexByType(RoomType.PickUp);
|
|
if (pickupIndex == -1)
|
|
{
|
|
Debug.Log("PickUp комнат не найдено але");
|
|
return;
|
|
}
|
|
|
|
var prefab = _factory.GetCachedPrefab(pickupIndex);
|
|
if (prefab == null)
|
|
return;
|
|
|
|
Room pickupRoom = prefab.GetComponent<Room>();
|
|
if (pickupRoom == null)
|
|
return;
|
|
|
|
if (_roomIndexesStack.Count == 0)
|
|
{
|
|
Debug.LogWarning("стек пуст, нет позиции после первой");
|
|
return;
|
|
}
|
|
|
|
int insertPos = Random.Range(1, _roomIndexesStack.Count + 1);
|
|
|
|
_roomIndexesStack.Insert(insertPos, pickupIndex);
|
|
Debug.Log($"PickUp комната '{pickupRoom.name}' позиция {insertPos}");
|
|
}
|
|
|
|
|
|
private void PlaceRoom(Room current, Room previous)
|
|
{
|
|
if (current.EnterMarker == null || previous.ExitMarker == null)
|
|
return;
|
|
|
|
Transform enter = current.EnterMarker;
|
|
Transform exit = previous.ExitMarker;
|
|
|
|
Quaternion rotationDiff = Quaternion.FromToRotation(enter.forward, exit.forward);
|
|
current.transform.rotation = rotationDiff * current.transform.rotation;
|
|
|
|
Vector3 offset = enter.localPosition;
|
|
current.transform.position = exit.position - offset;
|
|
}
|
|
}
|
|
}
|