Ахуеть, я сделал генерацию уровней на основе идеи Димки

This commit is contained in:
ThomasCharester committed 2025-11-28 10:27:49 +03:00
1 parent b7e9a26462
commit acd9cc1a32
52 files changed
+6333 -540

No files matched your search

@@ -6,35 +6,49 @@ using UnityEngine;
namespace Code.Generator
{
public class RoomGenerator : MonoBehaviour
public class RoomGenerator
{
private IOrderService _orderService;
[SerializeField] private GeneratorConfig generatorConfig;
private RoomGeneratorFactory _factory;
[Inject] private IOrderService _orderService;
[Inject] private GeneratorConfig generatorConfig;
[Inject] private IRoomGeneratorFactory _factory;
private List<RoomIndex> _roomIndexesStack;
private struct RoomIndex
{
public RoomType RoomType;
public int Index;
public RoomIndex(RoomType roomType, int index)
{
RoomType = roomType;
Index = index;
}
}
private List<int> _roomIndexesStack;
private List<Room> _spawnedRooms;
private int _nextRoomStackIndex;
[Inject]
private async void Construct(IOrderService orderService)
public void Initialize()
{
_orderService = orderService;
_orderService.OrderGive();
_factory = new RoomGeneratorFactory(generatorConfig);
// _orderService.OrderGive();
_spawnedRooms = new List<Room>();
_roomIndexesStack = new List<int>();
_roomIndexesStack = new();
Debug.LogWarning($"КОТЛЫ ГЕНЕРАЛЬСКИЕ{_orderService.DeliveryTimer}");
await _factory.PreloadRooms();
// CreateRoomsStack();
CreateRoomsStack();
await SpawnInitialRoomsAsync();
// SpawnInitialRoomsAsync();
_orderService.OnOrderGiven += CreateRoomsStack;
RoomTrigger.PlayerEnteredRoom += OnPlayerEntered;
CreateSaveRoom();
SpawnNextRoomAsync();
}
private void OnEnable()
@@ -46,117 +60,72 @@ namespace Code.Generator
{
RoomTrigger.PlayerEnteredRoom -= OnPlayerEntered;
}
public async void OnPlayerEntered()
{
await SpawnNextRoomAsync();
if (_spawnedRooms.Count > 2)
public void OnPlayerEntered()
{
SpawnNextRoomAsync();
if (_spawnedRooms.Count > 3)
{
Room roomToRemove = _spawnedRooms[0];
_spawnedRooms.RemoveAt(0);
_factory.ReleaseRoom(roomToRemove);
Destroy(roomToRemove.gameObject);
// _factory.ReleaseRoom(roomToRemove);
Object.Destroy(roomToRemove.gameObject);
}
}
private void CreateRoomsStack()
private void CreateRoomsStack(float timer)
{
var currentSaveRoom = _roomIndexesStack[^1];
_roomIndexesStack.Clear();
var remainingTime = _orderService.DeliveryTimer;
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)
_roomIndexesStack.Add(currentSaveRoom);
var remainingTime = timer;
while (remainingTime > 0)
{
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;
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.Basic, out int roomIndex);
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;
}
_roomIndexesStack.Add(new(RoomType.Basic, roomIndex));
remainingTime -= room.RoomTimer;
Debug.Log($"комната {room.name} время {room.RoomTimer} осталось: {remainingTime}");
}
AddPickupRoom();
CreateSaveRoom();
Debug.Log($"стек комнат: {_roomIndexesStack.Count}");
}
private void CreateSaveRoom()
{
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.Save, out int roomIndex);
Room saveRoom = prefab.GetComponent<Room>();
_roomIndexesStack.Add(new(RoomType.Save, roomIndex));
Debug.Log($"Первая комната: {saveRoom.name}");
}
private async UniTask SpawnInitialRoomsAsync()
{
_nextRoomStackIndex = 0;
await SpawnNextRoomAsync();
SpawnNextRoomAsync();
await SpawnNextRoomAsync();
SpawnNextRoomAsync();
}
private async UniTask SpawnNextRoomAsync()
private void SpawnNextRoomAsync()
{
if (_nextRoomStackIndex >= _roomIndexesStack.Count)
return;
int index = _roomIndexesStack[_nextRoomStackIndex];
Room room = await _factory.CreateRoomByIndex(index);
RoomIndex index = _roomIndexesStack[_nextRoomStackIndex];
Room room = _factory.CreateRoomByIndex(index.Index, index.RoomType);
if (_spawnedRooms.Count == 0)
{
@@ -172,70 +141,168 @@ namespace Code.Generator
_spawnedRooms.Add(room);
_nextRoomStackIndex++;
}
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;
var prefab = _factory.GetRandomCachedPrefabOfType(RoomType.PickUp, out int pickupIndex);
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);
int insertPos = Random.Range(1, _roomIndexesStack.Count + 1);
_roomIndexesStack.Insert(insertPos, new(RoomType.PickUp, 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;
Vector3 segmentOriginPosition = previous.ExitMarker.transform.position;
Quaternion rotationDiff = Quaternion.FromToRotation(enter.forward, exit.forward);
current.transform.rotation = rotationDiff * current.transform.rotation;
Transform randomDoorOrigin = current.EnterMarker;
Vector3 randomDoorOriginPosition = randomDoorOrigin.localPosition * current.transform.localScale.x;
Quaternion randomDoorOriginRotation = randomDoorOrigin.localRotation;
Vector3 offset = enter.localPosition;
current.transform.position = exit.position - offset;
float segmentOriginYRotation;
float entityRotation = previous.ExitMarker.transform.rotation.eulerAngles.y;
if (entityRotation > 305f) entityRotation -= 360f;
else if (entityRotation < -45f) entityRotation += 360f;
if (entityRotation > 135f)
segmentOriginYRotation = entityRotation - randomDoorOriginRotation.eulerAngles.y + 180f;
else
segmentOriginYRotation = entityRotation - randomDoorOriginRotation.eulerAngles.y - 180f;
if (segmentOriginYRotation < -45f) segmentOriginYRotation += 360f;
else if (segmentOriginYRotation > 305f) segmentOriginYRotation -= 360f;
else if (segmentOriginYRotation < -305f) segmentOriginYRotation += 720f;
if (segmentOriginYRotation is > -45f and < 45f)
{
segmentOriginPosition.x -= randomDoorOriginPosition.x;
segmentOriginPosition.z -= randomDoorOriginPosition.z;
}
else if (segmentOriginYRotation is >= 45f and < 135f)
{
segmentOriginPosition.x -= randomDoorOriginPosition.z;
segmentOriginPosition.z += randomDoorOriginPosition.x;
}
else if (segmentOriginYRotation is >= 135f and < 225f)
{
segmentOriginPosition.x += randomDoorOriginPosition.x;
segmentOriginPosition.z += randomDoorOriginPosition.z;
}
else if (segmentOriginYRotation is >= 225f and < 305f)
{
segmentOriginPosition.x += randomDoorOriginPosition.z;
segmentOriginPosition.z -= randomDoorOriginPosition.x;
}
segmentOriginPosition.y -= randomDoorOriginPosition.y;
current.transform.position = segmentOriginPosition;
current.transform.rotation = Quaternion.Euler(0, segmentOriginYRotation, 0);
// locationSegment.isNeedSomeDoors = true;
// locationSegment.AddBadDoorId(locationSegment.LocationSegment.GetDoorOrigins.IndexOf(randomDoorOrigin));
current.Initialize();
float frameOnTheBallRotation = segmentOriginYRotation + randomDoorOriginRotation.eulerAngles.y;
if (frameOnTheBallRotation > 305f) frameOnTheBallRotation -= 360f;
else if (frameOnTheBallRotation < -45f) frameOnTheBallRotation += 360f;
// heOnTheBall.AddSlaveLocationSegment(locationSegment.Id);
// heOnTheBall.ReplaceSlaveSegmentDoorOriginYRotation(frameOnTheBallRotation);
// heOnTheBall.isGotOnTheBall = false;
}
}
}
// private void CreateRoomsStackDimka()
// {
// _roomIndexesStack.Clear();
// var remainingTime = _orderService.DeliveryTimer;
// 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}");
// }