using Core; using Core.Lifecycle; using UI.Core; using Cinematics; using UnityEngine; using UnityEngine.Playables; using UnityEngine.UI; using System.Linq; using System.Collections.Generic; namespace UI { /// /// Manages player HUD elements and their visibility. /// Works alongside UIPageController (must be on same GameObject). /// Automatically hides HUD when pages open, shows when all pages close. /// public class PlayerHudManager : ManagedBehaviour { public enum UIMode { Overworld, Puzzle, Minigame, HideAll }; public UIMode currentUIMode; [Header("HUD Management")] [SerializeField] private Transform hudButtonsContainer; // Parent object containing all HUD buttons [Header("Cinematic References")] public GameObject landscapeObject; public GameObject portraitObject; public GameObject cinematicsParentObject; public GameObject CinematicBackground; [Header("HUD Elements")] public GameObject eagleEye; [HideInInspector] public Image cinematicSprites; [HideInInspector] public Image cinematicBackgroundSprites; [HideInInspector] public GameObject currentCinematicPlayer; [HideInInspector] public PlayableDirector playableDirector; private static PlayerHudManager _instance; public static PlayerHudManager Instance => _instance; private UIPageController _uiPageController; private AppSwitcher _appSwitcherComponent; private new void Awake() { base.Awake(); if (Instance != null) { Destroy(this); return; } _instance = this; // Get UIPageController on same GameObject _uiPageController = GetComponent(); if (_uiPageController == null) { UnityEngine.Debug.LogError("[PlayerHudManager] UIPageController not found on same GameObject!"); } InitializeReferences(); } protected override void OnManagedAwake() { // Subscribe to UIPageController page changes for auto HUD management if (_uiPageController != null) { _uiPageController.OnPageChanged += HandlePageStackChanged; } // Subscribe to CinematicsManager events for HUD management during cinematics if (CinematicsManager.Instance != null) { CinematicsManager.Instance.OnCinematicStarted += HandleCinematicStarted; CinematicsManager.Instance.OnCinematicStopped += HandleCinematicStopped; // Check if a cinematic is already playing if (CinematicsManager.Instance.IsCinematicPlaying) { HideAllHud(); Logging.Debug("[PlayerHudManager] Cinematic already playing on init, hiding HUD"); } } if (SceneManagerService.Instance != null) { SceneManagerService.Instance.SceneLoadCompleted += NewSceneLoaded; } if (SceneManagerService.Instance.CurrentGameplayScene == "AppleHillsOverworld") { NewSceneLoaded("AppleHillsOverworld"); } if (SceneManagerService.Instance.CurrentGameplayScene == "StartingScene") { // TODO: Hide all UI until cinematics have played NewSceneLoaded("AppleHillsOverworld"); } } protected override void OnDestroy() { base.OnDestroy(); // Unsubscribe from events if (_uiPageController != null) { _uiPageController.OnPageChanged -= HandlePageStackChanged; } if (CinematicsManager.Instance != null) { CinematicsManager.Instance.OnCinematicStarted -= HandleCinematicStarted; CinematicsManager.Instance.OnCinematicStopped -= HandleCinematicStopped; } if (SceneManagerService.Instance != null) { SceneManagerService.Instance.SceneLoadCompleted -= NewSceneLoaded; } } private void InitializeReferences() { currentCinematicPlayer = landscapeObject; playableDirector = cinematicsParentObject.GetComponent(); cinematicSprites = currentCinematicPlayer.GetComponent(); cinematicBackgroundSprites = CinematicBackground.GetComponent(); } private void UpateCinematicReferences(GameObject newCinematicPlayer) { currentCinematicPlayer = newCinematicPlayer; cinematicSprites = currentCinematicPlayer.GetComponent(); } public void SetPortraitMode(bool portraitModeEnable) { if (portraitModeEnable) { UpateCinematicReferences(portraitObject); } else { UpateCinematicReferences(landscapeObject); } } public void NewSceneLoaded(string sceneName) { switch (sceneName) { case "AppleHillsOverworld": UpdateUIMode(UIMode.Overworld); break; case "Quarry": UpdateUIMode(UIMode.Puzzle); break; case "DivingForPictures": UpdateUIMode(UIMode.Minigame); break; } } public void UpdateUIMode(UIMode mode) { switch (mode) { case UIMode.Overworld: // Update currentUIMode var currentUIMode = UIMode.Overworld; // Hide eagle eye eagleEye.SetActive(false); break; case UIMode.Puzzle: // Update currentUIMode var currentUIMode = UIMode.Puzzle; // show eagle eye eagleEye.SetActive(true); break; case UIMode.Minigame: // Update currentUIMode var currentUIMode = UIMode.Minigame; // Hide birds eye eagleEye.SetActive(false); break; } } /// /// Hides all HUD button elements /// public void HideAllHud() { SetHudVisibility(false); } /// /// Shows all HUD button elements /// public void ShowAllHud() { SetHudVisibility(true); } /// /// Hides all HUD elements except the specified exceptions /// /// GameObjects to keep visible public void HideAllHudExcept(params GameObject[] exceptions) { if (hudButtonsContainer == null) { Logging.Warning("[PlayerHudManager] HUD buttons container not assigned"); return; } HashSet exceptionSet = new HashSet(exceptions); foreach (Transform child in hudButtonsContainer) { bool shouldShow = exceptionSet.Contains(child.gameObject); child.gameObject.SetActive(shouldShow); } Logging.Debug($"[PlayerHudManager] Hidden HUD except {exceptions.Length} exceptions"); } /// /// Common method to set visibility of all HUD elements /// private void SetHudVisibility(bool visible) { if (hudButtonsContainer == null) { Logging.Warning("[PlayerHudManager] HUD buttons container not assigned"); return; } foreach (Transform child in hudButtonsContainer) { child.gameObject.SetActive(visible); } Logging.Debug($"[PlayerHudManager] {(visible ? "Shown" : "Hidden")} all HUD elements"); } /// /// Automatically manages HUD visibility based on page stack state /// private void HandlePageStackChanged(UIPage currentPage) { if (_uiPageController == null) return; // Use LINQ Count() on IEnumerable PageStack property int stackCount = _uiPageController.PageStack.Count(); if (stackCount == 1 && currentPage != null) { // First page just opened - hide HUD HideAllHud(); Logging.Debug("[PlayerHudManager] Page opened, hiding HUD"); } else if (stackCount == 0) { // Last page closed - show HUD ShowAllHud(); Logging.Debug("[PlayerHudManager] All pages closed, showing HUD"); } // If stackCount > 1, we're navigating between pages, keep HUD hidden } /// /// Called when a cinematic starts playing /// private void HandleCinematicStarted() { HideAllHud(); Logging.Debug("[PlayerHudManager] Cinematic started, hiding HUD"); } /// /// Called when a cinematic stops playing /// private void HandleCinematicStopped() { ShowAllHud(); Logging.Debug("[PlayerHudManager] Cinematic stopped, showing HUD"); } /// /// Convenience method to push a page from prefab using the UIPageController /// public void PushPageFromPrefab(GameObject pagePrefab) { if (_uiPageController != null) { _uiPageController.PushPageFromPrefab(pagePrefab); } else { UnityEngine.Debug.LogError("[PlayerHudManager] Cannot push page - UIPageController not found!"); } } } }