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();
}
}
}