Danro/Assets/Scripts/UI/LevelSelectModal.cs

105 lines
3.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RR.Common.UI
{
/// <summary>
/// Модальное окно выбора уровня.
/// Наследуется от Modal для автоматического управления фокусом и блокировки фона.
/// </summary>
public class LevelSelectModal : Modal
{
[Header("Контент")]
[SerializeField] private Transform content; // Grid parent
[SerializeField] private LevelButton levelButtonPrefab;
private readonly List<LevelButton> _levelsPool = new();
/// <summary>
/// Метод для открытия модального окна.
/// Переопределяет базовый метод для сборки кнопок перед открытием.
/// </summary>
public override void Open()
{
BuildIfNeeded();
base.Open();
}
// ==== ВНУТРЕННЕЕ ====
/// <summary>
/// Метод для сборки кнопок уровней
/// </summary>
private void BuildIfNeeded()
{
// Очистим/пересоберём
foreach (LevelButton b in _levelsPool.Where(b => b))
{
Destroy(b.gameObject);
}
_levelsPool.Clear();
List<LevelEntry> 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; }
/// <summary>
/// Метод для перебора уровней в игре
/// </summary>
/// <returns>LevelEntry - текущий мир при переборе</returns>
private static IEnumerable<LevelEntry> 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 };
}
}
}
}