using System.Collections.Generic; using System.IO; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace RR.Common.UI { /// /// Модальное окно выбора уровня для настройки награды за его прохождение. /// Строит список уровней из и /// предоставляет выбор текущего уровня как контекст для дальнейшего редактирования призов. /// public class LevelSettingsModal : Modal { [Header("References")] [SerializeField] private Transform contentRoot; [SerializeField] private GameObject levelButtonPrefab; [Header("Display")] [SerializeField] private bool rebuildOnOpen = true; [SerializeField] private bool includeOnlyLevelsFolder = true; [SerializeField] private string levelsFolderName = "Levels"; [SerializeField] private List ignoredSceneNames = new() { "MainMenu", "Level UI" }; [Header("Selection Visual")] [SerializeField] private Vector3 normalScale = Vector3.one; [SerializeField] private Vector3 selectedScale = new(1.05f, 1.05f, 1f); [Header("Модальное окно настройки приза")] [Tooltip("Ссылка на LevelPrizeSettingsModal. Открывается при нажатии на кнопку уровня.")] [SerializeField] private LevelPrizeSettingsModal levelPrizeSettingsModal; private readonly List _spawnedButtons = new(); private LevelButtonView _selectedButton; /// /// Имя сцены выбранного уровня. /// Используется внешними компонентами как ключ для загрузки или сохранения настроек приза. /// public string SelectedSceneName => _selectedButton != null ? _selectedButton.SceneName : string.Empty; /// /// Открывает окно выбора уровня. /// Перед открытием при необходимости пересобирает список кнопок из актуального набора сцен в Build Settings. /// public override void Open() { if (rebuildOnOpen || _spawnedButtons.Count == 0) { Rebuild(); } base.Open(); } [ContextMenu("Rebuild Level Buttons")] public void Rebuild() { if (!ValidateReferences()) { return; } ClearButtons(); List sceneNames = GetLevelSceneNames(); foreach (string t in sceneNames) { CreateButton(t); } if (_spawnedButtons.Count <= 0) return; SelectButton(_spawnedButtons[0]); SetFirstSelected(_spawnedButtons[0].Button); } /// /// Проверяет, что в инспекторе назначены контейнер для кнопок и префаб кнопки уровня. /// /// /// , если окно готово к построению списка уровней; /// иначе . /// private bool ValidateReferences() { if (contentRoot == null) { Debug.LogError($"[{nameof(LevelSettingsModal)}] Content Root is not assigned on {name}.", this); return false; } if (levelButtonPrefab == null) { Debug.LogError($"[{nameof(LevelSettingsModal)}] Level Button Prefab is not assigned on {name}.", this); return false; } return true; } /// /// Создает кнопку для конкретной сцены уровня и настраивает ее отображение. /// Нажатие на кнопку только выбирает уровень для последующей настройки награды. /// /// Имя сцены уровня, отображаемое в интерфейсе. private void CreateButton(string sceneName) { GameObject buttonObject = Instantiate(levelButtonPrefab, contentRoot); buttonObject.name = $"LevelButton_{sceneName}"; Button button = buttonObject.GetComponentInChildren