247 lines
6.3 KiB
C#
247 lines
6.3 KiB
C#
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<string, GameObject> screens = new();
|
|
private readonly Dictionary<string, GameObject> overlays = new();
|
|
|
|
public Button playButton; // â áîé
|
|
|
|
[Header("Invite UI (Overlay)")]
|
|
[SerializeField] private TMP_Text inviteText;
|
|
|
|
// Êîìïîíåíòû UI âûíåñåíû â îòäåëüíûå êëàññû
|
|
[SerializeField] private GameOverUI gameOverUI;
|
|
[SerializeField] private CoinUI coinUI;
|
|
|
|
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<string, GameObject> dict)
|
|
{
|
|
if (root == null) return;
|
|
|
|
var all = root.GetComponentsInChildren<UIPanelId>(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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Âîçâðàùàåò ïåðâûé àêòèâíûé overlay èëè null
|
|
/// </summary>
|
|
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<Button>();
|
|
if (firstButton != null)
|
|
{
|
|
var highlight = firstButton.GetComponent<UIButtonHighlight>();
|
|
if (highlight != null)
|
|
highlight.SetHighlighted(true);
|
|
}
|
|
}
|
|
|
|
OnPanelChanged?.Invoke();
|
|
}
|
|
|
|
public void HideAllOverlays()
|
|
{
|
|
foreach (var o in overlays.Values)
|
|
if (o != null) o.SetActive(false);
|
|
}
|
|
|
|
// ================== INVITE ==================
|
|
|
|
public void ShowInvite(int fromPlayerId)
|
|
{
|
|
if (inviteText != null)
|
|
inviteText.text = "Cûãðàåì?";
|
|
|
|
ShowOverlay("Invite", true, hideOtherOverlays: true);
|
|
}
|
|
|
|
public void HideInvite()
|
|
{
|
|
ShowOverlay("Invite", false);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
GameManager.OnInviteSent += HandleInvite;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
GameManager.OnInviteSent -= HandleInvite;
|
|
}
|
|
|
|
private void HandleInvite(int fromPlayerId, int toPlayerId)
|
|
{
|
|
if (toPlayerId != playerId) return;
|
|
|
|
if (!IsScreenActive("MainMenu")) return;
|
|
|
|
ShowInvite(fromPlayerId);
|
|
}
|
|
|
|
// ================== UI HELPERS ==================
|
|
|
|
private void ClearHighlights(GameObject panel)
|
|
{
|
|
var highlights = panel.GetComponentsInChildren<UIButtonHighlight>(true);
|
|
foreach (var h in highlights)
|
|
h.SetHighlighted(false);
|
|
}
|
|
|
|
private void ClearAllHighlights()
|
|
{
|
|
// Î÷èùàåì highlights íà âñåõ screens
|
|
foreach (var s in screens.Values)
|
|
if (s != null) ClearHighlights(s);
|
|
|
|
// Î÷èùàåì highlights íà âñåõ overlays
|
|
foreach (var o in overlays.Values)
|
|
if (o != null) ClearHighlights(o);
|
|
}
|
|
|
|
public void ShowTimer(bool show)
|
|
{
|
|
if (turnTimerUI == null) return;
|
|
if (show) turnTimerUI.StartTimer(); else turnTimerUI.StopTimer();
|
|
}
|
|
|
|
public void ShowGameOverMenu(bool isWin, bool isBotGame)
|
|
{
|
|
ShowScreen("GameOver");
|
|
|
|
if (gameOverUI != null)
|
|
gameOverUI.Show(isWin, isBotGame);
|
|
}
|
|
|
|
public void SetupPlayButtons(bool toggle)
|
|
{
|
|
if (playButton != null) playButton.interactable = toggle;
|
|
}
|
|
|
|
|
|
public bool ShowById(string id)
|
|
{
|
|
if (screens.TryGetValue(id, out var s))
|
|
{
|
|
ShowScreen(id);
|
|
return true;
|
|
}
|
|
|
|
if (overlays.TryGetValue(id, out var o))
|
|
{
|
|
ShowOverlay(id, true, hideOtherOverlays: true);
|
|
return true;
|
|
}
|
|
|
|
Debug.LogError($"UI id '{id}' íå íàéäåí íè â Screens, íè â Overlays");
|
|
return false;
|
|
}
|
|
|
|
}
|