using System; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using UnityEngine.UIElements; #if UNITY_EDITOR using UnityEditor; #endif namespace Hallucinate.UI { [RequireComponent(typeof(UIDocument))] public class UIManager : MonoBehaviour { public static UIManager Instance { get; private set; } private UIDocument _uiDocument; private VisualElement _rootElement; private readonly Dictionary _controllers = new Dictionary(); private readonly Stack _history = new Stack(); [Header("Game Metadata")] [SerializeField] private Texture2D gameIcon; [Header("UI Templates")] [SerializeField] private VisualTreeAsset mainMenuTemplate; [SerializeField] private VisualTreeAsset lobbyTemplate; [SerializeField] private VisualTreeAsset profileTemplate; [SerializeField] private VisualTreeAsset settingsTemplate; [SerializeField] private VisualTreeAsset hudTemplate; [Header("Debug Settings")] [SerializeField] private bool showDebugInfo = true; private MainMenuController _mainMenuController; private LobbyController _lobbyController; private ProfileController _profileController; private SettingsController _settingsController; private HUDController _hudController; private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); return; } _uiDocument = GetComponent(); _rootElement = _uiDocument.rootVisualElement; #if UNITY_EDITOR if (gameIcon == null) { var icons = PlayerSettings.GetIconsForTargetGroup(BuildTargetGroup.Unknown); if (icons != null && icons.Length > 0) gameIcon = icons[0]; } #endif InitializeControllers(); } private void InitializeControllers() { _mainMenuController = RegisterController(mainMenuTemplate); if (_mainMenuController != null && gameIcon != null) { _mainMenuController.SetGameIcon(gameIcon); } _lobbyController = RegisterController(lobbyTemplate); _profileController = RegisterController(profileTemplate); _settingsController = RegisterController(settingsTemplate); _hudController = RegisterController(hudTemplate); // Start with Main Menu _ = Push(); } private T RegisterController(VisualTreeAsset template) where T : BaseUIController, new() { if (template == null) { Debug.LogWarning($"Template for {typeof(T).Name} is missing!"); return null; } var instance = template.Instantiate(); instance.style.flexGrow = 1; instance.style.position = Position.Absolute; instance.style.width = Length.Percent(100); instance.style.height = Length.Percent(100); _rootElement.Add(instance); var controller = new T(); controller.Initialize(instance, this); _controllers[typeof(T)] = controller; return controller; } private void Update() { _mainMenuController?.Update(); _hudController?.Update(); } public async Task Push() where T : BaseUIController { if (!_controllers.TryGetValue(typeof(T), out var newScreen)) { Debug.LogError($"Controller of type {typeof(T)} not registered!"); return; } if (_history.Count > 0) { var currentScreen = _history.Peek(); await currentScreen.PlayTransitionOut(); } _history.Push(newScreen); await newScreen.PlayTransitionIn(); } public async Task Pop() { if (_history.Count <= 1) return; var currentScreen = _history.Pop(); await currentScreen.PlayTransitionOut(); var previousScreen = _history.Peek(); await previousScreen.PlayTransitionIn(); } } }