using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class UIManager : MonoBehaviour { // Событие для уведомления об изменении активной панели (для PlayerCursorUI) public System.Action OnPanelChanged; [SerializeField] private int playerId; public TurnTimerUI turnTimerUI; [Header("UI Roots")] [SerializeField] private Transform screensRoot; [SerializeField] private Transform overlaysRoot; // Реестры панелей по id private readonly Dictionary screens = new(); private readonly Dictionary overlays = new(); public Button playButton; // в бой [Header("Invite UI (Overlay)")] [SerializeField] private TMP_Text inviteText; // Компоненты UI вынесены в отдельные классы [SerializeField] private GameOverUI gameOverUI; [SerializeField] private CoinUI coinUI; [Header("GameOver Character Animation")] [SerializeField] private UIAnimatedMover gameOverCharacterMover; [SerializeField] private int gameOverWinCharacterIndex = 0; [SerializeField] private int gameOverLoseCharacterIndex = 0; private void Awake() { BuildRegistry(); } private void BuildRegistry() { screens.Clear(); overlays.Clear(); RegisterFromRoot(screensRoot, UIPanelLayer.Screen, screens); RegisterFromRoot(overlaysRoot, UIPanelLayer.Overlay, overlays); } private void RegisterFromRoot(Transform root, UIPanelLayer layer, Dictionary dict) { if (root == null) return; var all = root.GetComponentsInChildren(true); foreach (var p in all) { if (p.layer != layer) continue; if (string.IsNullOrWhiteSpace(p.id)) { Debug.LogWarning($"UIPanelId без id на объекте: {p.name}", p); continue; } if (!dict.TryAdd(p.id, p.gameObject)) Debug.LogWarning($"Дубликат UIPanelId.id='{p.id}'. Объект: {p.name}", p); } } private GameObject GetScreen(string id) => screens.TryGetValue(id, out var go) ? go : null; private GameObject GetOverlay(string id) => overlays.TryGetValue(id, out var go) ? go : null; public bool IsScreenActive(string id) { var s = GetScreen(id); return s != null && s.activeSelf; } /// /// Возвращает первый активный overlay или null /// public GameObject GetActiveOverlay() { foreach (var kvp in overlays) { if (kvp.Value != null && kvp.Value.activeSelf) return kvp.Value; } return null; } public GameObject GetActiveScreen() { foreach (var kvp in screens) { if (kvp.Value != null && kvp.Value.activeSelf) return kvp.Value; } return null; } // ================== PUBLIC API (NO STATES) ================== public void ShowScreen(string id, bool hideAllOverlays = true) { foreach (var s in screens.Values) if (s != null) s.SetActive(false); if (hideAllOverlays) HideAllOverlays(); var target = GetScreen(id); if (target == null) { Debug.LogError($"Screen '{id}' не найден. Проверь UIPanelId.id и что панель под ScreensRoot."); return; } target.SetActive(true); ClearHighlights(target); OnPanelChanged?.Invoke(); } public void ShowOverlay(string id, bool show = true, bool hideOtherOverlays = false) { if (hideOtherOverlays) HideAllOverlays(); var target = GetOverlay(id); if (target == null) { Debug.LogError($"Overlay '{id}' не найден."); return; } target.SetActive(show); if (show) { ClearAllHighlights(); var firstButton = target.GetComponentInChildren