313 lines
8.7 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;
[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<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();
}
/// <summary>
/// Ïîêàçûâàåò overlay ñ àíèìàöèåé ðàçâîðà÷èâàíèÿ
/// </summary>
public void ShowOverlayAnimated(string id, float delay = 0f, bool hideOtherOverlays = true)
{
if (hideOtherOverlays)
HideAllOverlays();
var target = GetOverlay(id);
if (target == null)
{
Debug.LogError($"Overlay '{id}' íå íàéäåí.");
return;
}
target.SetActive(true);
// Èùåì èëè äîáàâëÿåì UIPanelAnimator
var animator = target.GetComponent<UIPanelAnimator>();
if (animator == null)
{
animator = target.AddComponent<UIPanelAnimator>();
}
// Çàïóñêàåì àíèìàöèþ ñ çàäåðæêîé
if (delay > 0f)
animator.PlayShowAnimationWithDelay(delay);
else
animator.PlayShowAnimation();
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;
CreditSystem.OnInsufficientFunds += HandleInsufficientFunds;
}
private void OnDisable()
{
GameManager.OnInviteSent -= HandleInvite;
CreditSystem.OnInsufficientFunds -= HandleInsufficientFunds;
}
private void HandleInvite(int fromPlayerId, int toPlayerId)
{
if (toPlayerId != playerId) return;
if (!IsScreenActive("MainMenu")) return;
ShowInvite(fromPlayerId);
}
/// <summary>
/// Ïîêàçûâàåò ïàíåëü "Ïîïîëíèòå áàëàíñ" íóæíîìó èãðîêó.
/// Ïàíåëü äîëæíà èìåòü UIPanelId.id = "InsufficientFunds" (Overlay).
/// </summary>
private void HandleInsufficientFunds(int forPlayerId)
{
if (forPlayerId != playerId) return;
ShowOverlay("InsufficientFunds", true, hideOtherOverlays: false);
}
// ================== 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, Prize pendingPrize = null)
{
ShowScreen("GameOver");
if (gameOverUI != null)
gameOverUI.Show(isWin, isBotGame, pendingPrize);
// Çàïóñê UI-ïåðñîíàæà ïî íóæíîìó ïóòè (Victory/Defeat)
// if (gameOverCharacterMover != null)
// {
// gameOverCharacterMover.RemoveAllCharacters();
//
// int idx = isWin ? gameOverWinCharacterIndex : gameOverLoseCharacterIndex;
// gameOverCharacterMover.InitializeByIndex(idx, isWin ? PathType.Victory : PathType.Defeat);
// }
}
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;
}
}