using System; using Core; using UnityEngine; using UnityEngine.SceneManagement; using Input; using Bootstrap; namespace UI { public class PauseMenu : MonoBehaviour, ITouchInputConsumer { private static PauseMenu _instance; private static bool _isQuitting; /// /// Singleton instance of the PauseMenu. No longer creates an instance if one doesn't exist. /// public static PauseMenu Instance => _instance; [Header("UI References")] [SerializeField] private GameObject pauseMenuPanel; [SerializeField] private GameObject pauseButton; public event Action OnGamePaused; public event Action OnGameResumed; private bool _isPaused = false; /// /// Returns whether the game is currently paused /// public bool IsPaused => _isPaused; private void Awake() { _instance = this; // Register for post-boot initialization BootCompletionService.RegisterInitAction(InitializePostBoot); } private void InitializePostBoot() { // Subscribe to scene loaded events SceneManagerService.Instance.SceneLoadCompleted += SetPauseMenuByLevel; // SceneManagerService subscription moved to InitializePostBoot // Set initial state based on current scene SetPauseMenuByLevel(SceneManager.GetActiveScene().name); #if UNITY_EDITOR // Initialize pause menu state HidePauseMenu(false); #endif Logging.Debug("[PauseMenu] Subscribed to SceneManagerService events"); } private void OnDestroy() { // Unsubscribe when destroyed if (SceneManagerService.Instance != null) { SceneManagerService.Instance.SceneLoadCompleted -= SetPauseMenuByLevel; } } void OnApplicationQuit() { _isQuitting = true; } /// /// Sets the pause menu game object active or inactive based on the current level /// /// The name of the level/scene public void SetPauseMenuByLevel(string levelName) { if (string.IsNullOrEmpty(levelName)) return; bool isMainMenu = levelName.ToLower().Contains("mainmenu"); bool isStartingLevel = levelName.ToLower().Contains("startingscene"); gameObject.SetActive(!(isMainMenu || isStartingLevel)); if(!isMainMenu && !isStartingLevel) HidePauseMenu(false); // Ensure menu is hidden when switching to a game level Logging.Debug($"[PauseMenu] Setting pause menu active: {!isMainMenu} for scene: {levelName}"); } /// /// Shows the pause menu and hides the pause button. Sets input mode to UI. /// public void ShowPauseMenu() { if (pauseMenuPanel != null) pauseMenuPanel.SetActive(true); if (pauseButton != null) pauseButton.SetActive(false); // Set paused flag and broadcast event _isPaused = true; InputManager.Instance.SetInputMode(InputMode.UI); OnGamePaused?.Invoke(); Logging.Debug("[PauseMenu] Game Paused"); } /// /// Hides the pause menu and shows the pause button. Sets input mode to Game. /// public void HidePauseMenu(bool resetInput = true) { if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false); if (pauseButton != null) pauseButton.SetActive(true); // Clear paused flag and broadcast event _isPaused = false; InputManager.Instance.SetInputMode(InputMode.GameAndUI); OnGameResumed?.Invoke(); Logging.Debug("[PauseMenu] Game Resumed"); } /// /// Resumes the game by hiding the pause menu. /// public void ResumeGame() { HidePauseMenu(); } /// /// Exits to the main menu scene. /// public async void ExitToMainMenu() { // Replace with the actual scene name as set in Build Settings var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.SwitchSceneAsync("MainMenu", progress); } /// /// Exits the application. /// public void ExitGame() { #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } public async void ReloadLevel() { var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); await SceneManagerService.Instance.ReloadCurrentScene(progress); } /// /// Loads a level based on the selection from a dropdown menu. /// Connect this to a Dropdown's onValueChanged event and pass the selected option text. /// /// The selected level name or identifier from the dropdown public async void LoadLevel(int levelSelection) { // Hide the pause menu before loading a new level HidePauseMenu(); // Replace with the actual scene name as set in Build Settings var progress = new Progress(p => Logging.Debug($"Loading progress: {p * 100:F0}%")); switch (levelSelection) { case 0: await SceneManagerService.Instance.SwitchSceneAsync("MainMenu", progress); break; case 1: await SceneManagerService.Instance.SwitchSceneAsync("AppleHillsOverworld", progress); break; case 2: await SceneManagerService.Instance.SwitchSceneAsync("Quarry", progress); break; case 3: await SceneManagerService.Instance.SwitchSceneAsync("DivingForPictures", progress); break; } } public void OnTap(Vector2 position) { ShowPauseMenu(); } public void OnHoldStart(Vector2 position) { throw new NotImplementedException(); } public void OnHoldMove(Vector2 position) { throw new NotImplementedException(); } public void OnHoldEnd(Vector2 position) { throw new NotImplementedException(); } } }