using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; using UnityEngine.InputSystem; public class PauseMenu : MonoBehaviour { [Header("Панели")] public GameObject pauseMenuPanel; public GameObject settingsPanel; [Header("Кнопки панели действий")] public Button resumeButton; public Button restartButton; public Button mainMenuButton; public Button quitButton; [Header("Вкладки")] public Button[] tabButtons; public GameObject[] tabPanels; [Header("Настройки: Звук")] public Slider volumeSlider; public Text volumeValueText; public Toggle muteToggle; [Header("Настройки: Графика")] public Dropdown qualityDropdown; public Toggle fullscreenToggle; public Dropdown resolutionDropdown; public Toggle vsyncToggle; [Header("Настройки: Управление")] public Slider sensitivitySlider; public Text sensitivityValueText; public Toggle invertYToggle; private bool isPaused = false; private bool isInitializing = false; private bool wasCursorLocked = false; private List filteredResolutions = new List(); public bool IsPaused => isPaused; private void Awake() { AutoWireUI(); } private void Start() { AutoWireUI(); if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false); if (settingsPanel != null && settingsPanel != pauseMenuPanel) settingsPanel.SetActive(false); SetupActionButtons(); SetupTabs(); InitializeSettingsUI(); wasCursorLocked = (Cursor.lockState == CursorLockMode.Locked); } private void Update() { // Не открываем меню паузы, если активен экран смерти if (DeathScreenUI.Instance != null && DeathScreenUI.Instance.IsShown) return; bool togglePause = false; var keyboard = Keyboard.current; if (keyboard != null) { if (keyboard.escapeKey.wasPressedThisFrame || keyboard.pKey.wasPressedThisFrame || keyboard.tabKey.wasPressedThisFrame || keyboard.pauseKey.wasPressedThisFrame) { togglePause = true; } } var gamepad = Gamepad.current; if (gamepad != null && gamepad.startButton.wasPressedThisFrame) { togglePause = true; } #if UNITY_EDITOR // В Unity Editor при заблокированном курсоре нажатие Escape перехватывается редактором // для снятия блокировки курсора (Cursor.lockState переключается в None) и не передается в Update(). // Поэтому в редакторе переключение lockState из Locked в None трактуется как нажатие Escape! if (!isPaused && wasCursorLocked && Cursor.lockState != CursorLockMode.Locked) { togglePause = true; } wasCursorLocked = (Cursor.lockState == CursorLockMode.Locked); #endif if (togglePause) { if (isPaused) { if (settingsPanel != null && settingsPanel.activeSelf && settingsPanel != pauseMenuPanel) { CloseSettings(); } else { ResumeGame(); } } else { PauseGame(); } } } public void PauseGame() { isPaused = true; Time.timeScale = 0f; Cursor.lockState = CursorLockMode.None; Cursor.visible = true; wasCursorLocked = false; if (pauseMenuPanel != null) { pauseMenuPanel.SetActive(true); SwitchTab(0); } if (settingsPanel != null && settingsPanel != pauseMenuPanel) { settingsPanel.SetActive(false); } Debug.Log("[PauseMenu] Game PAUSED (Esc/P/Tab pressed). Time.timeScale=0."); } public void ResumeGame() { isPaused = false; Time.timeScale = 1f; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; wasCursorLocked = true; if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false); if (settingsPanel != null) settingsPanel.SetActive(false); Debug.Log("[PauseMenu] Game RESUMED. Time.timeScale=1."); } public void RestartGame() { Time.timeScale = 1f; Cursor.lockState = CursorLockMode.Locked; Cursor.visible = false; SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void OpenSettings() { if (pauseMenuPanel != null) pauseMenuPanel.SetActive(false); if (settingsPanel != null) settingsPanel.SetActive(true); } public void CloseSettings() { PlayerPrefs.Save(); if (settingsPanel != null) settingsPanel.SetActive(false); if (pauseMenuPanel != null) pauseMenuPanel.SetActive(true); } public void ReturnToMainMenu() { Time.timeScale = 1f; Cursor.lockState = CursorLockMode.None; Cursor.visible = true; SceneManager.LoadScene("MainMenu"); } public void QuitGame() { PlayerPrefs.Save(); Application.Quit(); #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #endif } public void SwitchTab(int tabIndex) { if (tabPanels != null) { for (int i = 0; i < tabPanels.Length; i++) { if (tabPanels[i] != null) { tabPanels[i].SetActive(i == tabIndex); } } } if (tabButtons != null) { for (int i = 0; i < tabButtons.Length; i++) { if (tabButtons[i] != null) { bool isActive = (i == tabIndex); var img = tabButtons[i].GetComponent(); if (img != null) { img.color = isActive ? new Color(0.00f, 0.65f, 0.85f, 0.95f) // Неоновый бирюзовый акцент : new Color(0.06f, 0.10f, 0.16f, 0.85f); // Темный фон неактивной вкладки } var text = tabButtons[i].GetComponentInChildren(); if (text != null) { text.color = isActive ? Color.white : new Color(0.40f, 0.55f, 0.65f, 0.80f); } } } } } private void SetupTabs() { if (tabButtons != null) { for (int i = 0; i < tabButtons.Length; i++) { int index = i; tabButtons[i].onClick.RemoveAllListeners(); tabButtons[i].onClick.AddListener(() => SwitchTab(index)); } } } private void SetupActionButtons() { if (resumeButton != null) { resumeButton.onClick.RemoveAllListeners(); resumeButton.onClick.AddListener(ResumeGame); } if (restartButton != null) { restartButton.onClick.RemoveAllListeners(); restartButton.onClick.AddListener(RestartGame); } if (mainMenuButton != null) { mainMenuButton.onClick.RemoveAllListeners(); mainMenuButton.onClick.AddListener(ReturnToMainMenu); } if (quitButton != null) { quitButton.onClick.RemoveAllListeners(); quitButton.onClick.AddListener(QuitGame); } } public void AutoWireUI() { if (pauseMenuPanel == null) { var root = transform.Find("PauseRootPanel"); if (root != null) { pauseMenuPanel = root.gameObject; } else { var panel = transform.Find("PauseMenuPanel"); if (panel != null) pauseMenuPanel = panel.gameObject; } } Transform window = transform.Find("PauseRootPanel/Settings_Window"); if (window != null) { var winRt = window.GetComponent(); if (winRt != null && (winRt.sizeDelta.x <= 0f || winRt.sizeDelta.y <= 0f)) { winRt.anchorMin = new Vector2(0.5f, 0.5f); winRt.anchorMax = new Vector2(0.5f, 0.5f); winRt.pivot = new Vector2(0.5f, 0.5f); winRt.anchoredPosition = Vector2.zero; winRt.sizeDelta = new Vector2(1100f, 720f); } Transform dock = window.Find("Bottom_Action_Dock"); if (dock != null) { if (resumeButton == null) resumeButton = dock.Find("Btn_Resume")?.GetComponent