136 lines
No EOL
4.7 KiB
C#
136 lines
No EOL
4.7 KiB
C#
using UnityEngine;
|
||
using System.Collections.Generic;
|
||
|
||
public class LevelGenerator : MonoBehaviour
|
||
{
|
||
[System.Serializable]
|
||
public struct DifficultyTier
|
||
{
|
||
[Range(0, 1)] public float startPercentage; // Начало этапа (0.0 = 0%)
|
||
public List<GameObject> chunkPrefabs; // Префабы для этого этапа
|
||
public Vector3 gravityValue;
|
||
}
|
||
|
||
[Header("Settings")]
|
||
[SerializeField] private Transform playerTransform;
|
||
[SerializeField] private int totalChunksLimit = 50; // Лимит уровня
|
||
[SerializeField] private int initialChunks = 4; // Сколько спавним сразу
|
||
[SerializeField] private float spawnDistance = 20f; // Дистанция до последнего чанка для спавна нового
|
||
[SerializeField] private List<DifficultyTier> difficultyTiers;
|
||
|
||
[Header("Pool Settings")]
|
||
private Queue<Chunk> activeChunks = new Queue<Chunk>();
|
||
private Dictionary<int, Queue<Chunk>> pool = new Dictionary<int, Queue<Chunk>>();
|
||
|
||
private Vector3 nextSpawnPoint;
|
||
private int chunksSpawned = 0;
|
||
|
||
void Start()
|
||
{
|
||
UpdateWorldGravity();
|
||
// Начальная точка — позиция генератора
|
||
nextSpawnPoint = transform.position;
|
||
|
||
for (int i = 0; i < initialChunks; i++)
|
||
{
|
||
SpawnNextChunk();
|
||
}
|
||
}
|
||
|
||
private void UpdateWorldGravity()
|
||
{
|
||
float progress = (float)chunksSpawned / totalChunksLimit;
|
||
Vector3 targetGravity = difficultyTiers[0].gravityValue;
|
||
|
||
|
||
// Ищем гравитацию текущего тира (аналогично логике выбора префабов)
|
||
foreach (var tier in difficultyTiers)
|
||
{
|
||
if (progress >= tier.startPercentage)
|
||
{
|
||
targetGravity = tier.gravityValue;
|
||
}
|
||
}
|
||
|
||
// Применяем гравитацию
|
||
Physics2D.gravity = targetGravity;
|
||
Debug.Log($"Current Gravity: {Physics.gravity} | Progress: {progress}");
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
// Проверяем расстояние до последнего чанка
|
||
if (chunksSpawned < totalChunksLimit)
|
||
{
|
||
float distanceToLast = Vector3.Distance(playerTransform.position, nextSpawnPoint);
|
||
if (distanceToLast < spawnDistance)
|
||
{
|
||
SpawnNextChunk();
|
||
}
|
||
}
|
||
|
||
// Очистка старых чанков (удаляем, если игрок ушел далеко)
|
||
if (activeChunks.Count > 0)
|
||
{
|
||
Chunk oldest = activeChunks.Peek();
|
||
// Расстояние берем с запасом, чтобы чанк не исчез на глазах
|
||
if (Vector3.Distance(playerTransform.position, oldest.transform.position) > spawnDistance * 2)
|
||
{
|
||
RecycleChunk(activeChunks.Dequeue());
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SpawnNextChunk()
|
||
{
|
||
UpdateWorldGravity();
|
||
GameObject prefab = GetRandomPrefabByProgress();
|
||
Chunk chunk = GetChunkFromPool(prefab);
|
||
|
||
chunk.AlignTo(nextSpawnPoint);
|
||
nextSpawnPoint = chunk.exit.position;
|
||
|
||
activeChunks.Enqueue(chunk);
|
||
chunksSpawned++;
|
||
}
|
||
|
||
private GameObject GetRandomPrefabByProgress()
|
||
{
|
||
float progress = (float)chunksSpawned / totalChunksLimit;
|
||
DifficultyTier currentTier = difficultyTiers[0];
|
||
|
||
// Ищем подходящий тир сложности по прогрессу
|
||
foreach (var tier in difficultyTiers)
|
||
{
|
||
if (progress >= tier.startPercentage)
|
||
currentTier = tier;
|
||
}
|
||
|
||
return currentTier.chunkPrefabs[Random.Range(0, currentTier.chunkPrefabs.Count)];
|
||
}
|
||
|
||
// --- Логика Object Pooling ---
|
||
private Chunk GetChunkFromPool(GameObject prefab)
|
||
{
|
||
int id = prefab.GetInstanceID();
|
||
if (!pool.ContainsKey(id)) pool[id] = new Queue<Chunk>();
|
||
|
||
if (pool[id].Count > 0)
|
||
{
|
||
Chunk chunk = pool[id].Dequeue();
|
||
chunk.gameObject.SetActive(true);
|
||
return chunk;
|
||
}
|
||
|
||
return Instantiate(prefab).GetComponent<Chunk>();
|
||
}
|
||
|
||
private void RecycleChunk(Chunk chunk)
|
||
{
|
||
chunk.gameObject.SetActive(false);
|
||
// Мы не знаем ID префаба здесь напрямую в этой упрощенной версии,
|
||
// в идеале хранить ID в скрипте Chunk. Для примера просто Destroy:
|
||
Destroy(chunk.gameObject);
|
||
// Примечание: Для полноценного пулинга добавьте int prefabID в класс Chunk
|
||
}
|
||
} |