115 lines
4.2 KiB
C#
115 lines
4.2 KiB
C#
using UnityEngine;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
|
||
public class LevelGenerator : MonoBehaviour
|
||
{
|
||
// Публичные поля для префабов удалены. Теперь все берется из ThemeManager.
|
||
private Transform playerTransform;
|
||
public int numberOfPlatforms = 5;
|
||
public float platformLength = 50f;
|
||
public float laneWidth = 4f;
|
||
public float highObstacleYOffset = 1.5f;
|
||
|
||
private VisualTheme currentTheme;
|
||
private Dictionary<GameObject, List<GameObject>> platformItems = new Dictionary<GameObject, List<GameObject>>();
|
||
private List<GameObject> activePlatforms = new List<GameObject>();
|
||
private float spawnPosition = 0f;
|
||
|
||
void Start()
|
||
{
|
||
currentTheme = ThemeManager.Instance.GetCurrentTheme();
|
||
if (currentTheme == null)
|
||
{
|
||
Debug.LogError("Не удалось загрузить тему в LevelGenerator!");
|
||
return;
|
||
}
|
||
|
||
// Применяем скайбокс темы
|
||
RenderSettings.skybox = currentTheme.skyboxMaterial;
|
||
|
||
// Спавним игрока
|
||
GameObject player = Instantiate(currentTheme.playerPrefab, new Vector3(0, 1, 0), Quaternion.identity);
|
||
playerTransform = player.transform;
|
||
|
||
// Спавним стартовые платформы
|
||
for (int i = 0; i < numberOfPlatforms; i++) SpawnPlatform();
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (playerTransform == null) return;
|
||
|
||
if (playerTransform.position.z - platformLength > spawnPosition - (numberOfPlatforms * platformLength))
|
||
{
|
||
SpawnPlatform();
|
||
DeleteOldestPlatform();
|
||
}
|
||
}
|
||
|
||
private void SpawnPlatform()
|
||
{
|
||
GameObject newPlatform = Instantiate(currentTheme.platformPrefab, Vector3.forward * spawnPosition, Quaternion.Euler(0, 90, 0));
|
||
activePlatforms.Add(newPlatform);
|
||
platformItems[newPlatform] = new List<GameObject>();
|
||
PopulatePlatformByLanes(newPlatform);
|
||
spawnPosition += platformLength;
|
||
}
|
||
|
||
private void PopulatePlatformByLanes(GameObject platform)
|
||
{
|
||
int segments = 5;
|
||
float segmentLength = platformLength / segments;
|
||
List<Vector3> spawnPoints = new List<Vector3>();
|
||
|
||
for (int i = 0; i < segments; i++)
|
||
{
|
||
for (int j = -1; j <= 1; j++)
|
||
{
|
||
float zPos = platform.transform.position.z - (platformLength / 2) + (i * segmentLength) + (segmentLength / 2);
|
||
float xPos = j * laneWidth;
|
||
spawnPoints.Add(new Vector3(xPos, 0, zPos));
|
||
}
|
||
}
|
||
|
||
System.Random rng = new System.Random();
|
||
spawnPoints = spawnPoints.OrderBy(a => rng.Next()).ToList();
|
||
|
||
int itemsToSpawn = Random.Range(5, 10);
|
||
|
||
for (int i = 0; i < itemsToSpawn && i < spawnPoints.Count; i++)
|
||
{
|
||
GameObject itemToSpawn = null;
|
||
Vector3 spawnPos = spawnPoints[i];
|
||
|
||
int itemType = Random.Range(0, 25);
|
||
switch (itemType)
|
||
{
|
||
case 0: itemToSpawn = currentTheme.invincibilityBonusPrefab; spawnPos.y = 1f; break;
|
||
case 1: case 2: itemToSpawn = currentTheme.highObstaclePrefab; spawnPos.y = highObstacleYOffset; break;
|
||
case 3: case 4: itemToSpawn = currentTheme.movingObstaclePrefab; spawnPos.y = 1f; break;
|
||
case 5: case 6: case 7: itemToSpawn = currentTheme.lowObstaclePrefab; spawnPos.y = 1f; break;
|
||
default: itemToSpawn = currentTheme.coinPrefab; spawnPos.y = 1f; break;
|
||
}
|
||
|
||
if (itemToSpawn != null)
|
||
{
|
||
GameObject newItem = Instantiate(itemToSpawn, spawnPos, Quaternion.identity);
|
||
platformItems[platform].Add(newItem);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void DeleteOldestPlatform()
|
||
{
|
||
GameObject platformToDelete = activePlatforms[0];
|
||
if (platformItems.ContainsKey(platformToDelete))
|
||
{
|
||
foreach (GameObject item in platformItems[platformToDelete]) Destroy(item);
|
||
platformItems.Remove(platformToDelete);
|
||
}
|
||
Destroy(platformToDelete);
|
||
activePlatforms.RemoveAt(0);
|
||
}
|
||
}
|