using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; namespace UI { public class UIManager : MonoBehaviour { public static UIManager Instance { get; private set; } [System.Serializable] public class ScreenData { public string screenName; // Phải khớp với chuỗi gọi trong ShowScreen public UIDocument document; public bool isActive; public bool isOverlay; public Texture2D customCursor; } public List screens = new List(); [Header("Default Settings")] public Texture2D defaultCursor; public string initialScreen = "MainMenu"; private string _currentScreenName; private void Awake() { if (Instance == null) Instance = this; else Destroy(gameObject); // Khởi tạo trạng thái ban đầu: Ẩn tất cả trừ màn hình mặc định foreach (var screen in screens) { if (screen.document == null) continue; if (screen.screenName == "Settings") screen.document.sortingOrder = 999; screen.isActive = (screen.screenName == initialScreen); screen.document.rootVisualElement.style.display = screen.isActive ? DisplayStyle.Flex : DisplayStyle.None; } _currentScreenName = initialScreen; } private void Update() { if (Input.GetKeyDown(KeyCode.Escape)) ToggleSettings(); HandleAltCursor(); } private void HandleAltCursor() { // Only handle Alt cursor when we are in game (HUD is active) // and Settings is NOT currently toggled on. var settingsData = screens.Find(s => s.screenName == "Settings"); bool settingsActive = settingsData != null && settingsData.isActive; if (_currentScreenName == "HUD" && !settingsActive) { if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) { UnityEngine.Cursor.visible = true; UnityEngine.Cursor.lockState = CursorLockMode.None; } else { UnityEngine.Cursor.visible = false; UnityEngine.Cursor.lockState = CursorLockMode.Locked; } } } public void ShowOnly(string name) => ShowScreen(name); public void ShowScreen(string name) { if (_currentScreenName == name) return; // Kiểm tra xem màn hình mục tiêu có tồn tại không trước khi tắt cái cũ var nextData = screens.Find(s => s.screenName == name); if (nextData == null) { Debug.LogError($"[UIManager] Screen '{name}' not found in the list! Check your Inspector names."); return; } StartCoroutine(TransitionRoutine(nextData)); } private IEnumerator TransitionRoutine(ScreenData nextData) { // 1. Fade Out các màn hình chính hiện tại (trừ Overlay) foreach (var s in screens) { if (s.isActive && !s.isOverlay) { var root = s.document.rootVisualElement.Q(); if (root != null) root.AddToClassList("hidden"); s.isActive = false; } } yield return new WaitForSeconds(0.3f); SyncScreens(); // Ẩn hẳn display // 2. Hiện màn hình mới nextData.isActive = true; _currentScreenName = nextData.screenName; var nextRoot = nextData.document.rootVisualElement.Q(); if (nextRoot != null) { nextData.document.rootVisualElement.style.display = DisplayStyle.Flex; nextRoot.AddToClassList("hidden"); yield return null; // Chờ 1 frame để UI Toolkit cập nhật nextRoot.RemoveFromClassList("hidden"); } ApplyCursor(nextData.customCursor != null ? nextData.customCursor : defaultCursor); } public void ToggleSettings() { var settingsData = screens.Find(s => s.screenName == "Settings"); if (settingsData == null) return; settingsData.isActive = !settingsData.isActive; settingsData.document.rootVisualElement.style.display = settingsData.isActive ? DisplayStyle.Flex : DisplayStyle.None; if (settingsData.isActive) { UnityEngine.Cursor.visible = true; UnityEngine.Cursor.lockState = CursorLockMode.None; ApplyCursor(settingsData.customCursor != null ? settingsData.customCursor : defaultCursor); } else { // Nếu tắt Settings, quay về trạng thái của màn hình hiện tại var current = screens.Find(s => s.screenName == _currentScreenName); if (current != null) ApplyCursor(current.customCursor != null ? current.customCursor : defaultCursor); // Tùy vào game là FPS hay Menu mà ẩn chuột if (_currentScreenName == "HUD") { UnityEngine.Cursor.visible = false; UnityEngine.Cursor.lockState = CursorLockMode.Locked; } } } public void SyncScreens() { foreach (var screen in screens) { if (screen.document != null && screen.document.rootVisualElement != null) { screen.document.rootVisualElement.style.display = screen.isActive ? DisplayStyle.Flex : DisplayStyle.None; } } } private void ApplyCursor(Texture2D texture) { UnityEngine.Cursor.SetCursor(texture, Vector2.zero, CursorMode.Auto); } } }