using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RR.Common.UI
{
///
/// Модальное окно выбора уровня.
/// Наследуется от Modal для автоматического управления фокусом и блокировки фона.
///
public class LevelSelectModal : Modal
{
[Header("Контент")]
[SerializeField] private Transform content; // Grid parent
[SerializeField] private LevelButton levelButtonPrefab;
private readonly List _levelsPool = new();
///
/// Метод для открытия модального окна.
/// Переопределяет базовый метод для сборки кнопок перед открытием.
///
public override void Open()
{
BuildIfNeeded();
base.Open();
}
// ==== ВНУТРЕННЕЕ ====
///
/// Метод для сборки кнопок уровней
///
private void BuildIfNeeded()
{
// Очистим/пересоберём
foreach (LevelButton b in _levelsPool.Where(b => b))
{
Destroy(b.gameObject);
}
_levelsPool.Clear();
List levels = EnumerateLevelScenesInBuild()
.OrderBy(e => e.world)
.ThenBy(e => e.stage)
.ToList();
foreach (LevelEntry _ in levels)
{
LevelButton btn = Instantiate(levelButtonPrefab, content);
_levelsPool.Add(btn);
}
for (int index = 0; index < _levelsPool.Count; index++)
{
LevelButton btn = _levelsPool[index];
btn.Setup(
$"{levels[index].world}-{levels[index].stage}",
levels[index].world,
levels[index].stage);
switch (levels[index].world)
{
case 1:
btn.SetColor(Color.green);
break;
case 2:
btn.SetColor(Color.blue);
break;
}
}
}
private struct LevelEntry { public int world; public int stage; }
///
/// Метод для перебора уровней в игре
///
/// LevelEntry - текущий мир при переборе
private static IEnumerable EnumerateLevelScenesInBuild()
{
int n = SceneManager.sceneCountInBuildSettings;
for (int i = 0; i < n; i++)
{
string path = SceneUtility.GetScenePathByBuildIndex(i);
string sceneName = System.IO.Path.GetFileNameWithoutExtension(path);
// фильтр "только уровни" по формату имени W-S:
string[] parts = sceneName.Split('-');
if (parts.Length != 2) continue;
if (!int.TryParse(parts[0], out int world)) continue;
if (!int.TryParse(parts[1], out int stage)) continue;
// Исключим служебные сцены
if (sceneName.Equals("Level UI", System.StringComparison.OrdinalIgnoreCase)) continue;
if (sceneName.Equals("MainMenu", System.StringComparison.OrdinalIgnoreCase)) continue;
yield return new LevelEntry { world = world, stage = stage };
}
}
}
}