using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using UnityEngine.InputSystem.UI; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine.SceneManagement; public static class PauseMenuBuilder { private static DefaultControls.Resources uiResources; private static Font standardFont; [MenuItem("Tools/Add Pause Menu to SampleScene")] public static string Build() { standardFont = Resources.GetBuiltinResource("LegacyRuntime.ttf"); if (standardFont == null) standardFont = Resources.GetBuiltinResource("Arial.ttf"); uiResources = new DefaultControls.Resources { standard = AssetDatabase.GetBuiltinExtraResource("UI/Skin/UISprite.psd"), background = AssetDatabase.GetBuiltinExtraResource("UI/Skin/Background.psd"), knob = AssetDatabase.GetBuiltinExtraResource("UI/Skin/Knob.psd"), checkmark = AssetDatabase.GetBuiltinExtraResource("UI/Skin/Checkmark.psd"), dropdown = AssetDatabase.GetBuiltinExtraResource("UI/Skin/DropdownArrow.psd"), mask = AssetDatabase.GetBuiltinExtraResource("UI/Skin/UIMask.psd") }; // Открываем сцену геймплея Scene gameplayScene = EditorSceneManager.OpenScene("Assets/Scenes/SampleScene.unity", OpenSceneMode.Single); // Проверяем EventSystem if (Object.FindAnyObjectByType() == null) { GameObject esGo = new GameObject("EventSystem"); esGo.AddComponent(); esGo.AddComponent(); } // Пересоздаем PauseCanvas var old = GameObject.Find("PauseCanvas"); if (old != null) Object.DestroyImmediate(old); // Создаем Canvas паузы GameObject canvasGo = new GameObject("PauseCanvas"); Canvas canvas = canvasGo.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; canvas.sortingOrder = 100; // Поверх игрового мира CanvasScaler scaler = canvasGo.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1920, 1080); scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight; scaler.matchWidthOrHeight = 0.5f; canvasGo.AddComponent(); PauseMenu pauseMenu = canvasGo.AddComponent(); // Цвета стилистики Главного Меню (Synthesia Minimalist Black & Yellow) Color yellowBtnNormal = new Color(0.95f, 0.78f, 0.12f, 1.00f); Color yellowBtnHover = new Color(1.00f, 0.90f, 0.35f, 1.00f); Color yellowBtnPress = new Color(0.78f, 0.62f, 0.08f, 1.00f); Color blackBtnText = new Color(0.06f, 0.06f, 0.06f, 1.00f); // ========================================== // 1. КАРТОЧКА МЕНЮ ПАУЗЫ (PauseMenuPanel) // ========================================== GameObject pausePanel = CreateImage("PauseMenuPanel", canvasGo.transform, new Color(0.0f, 0.0f, 0.0f, 0.88f), Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); GameObject pauseCard = CreateImage("Pause_Card", pausePanel.transform, new Color(0.04f, 0.04f, 0.04f, 0.98f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(480f, 560f), Vector2.zero); Outline cardOutline = pauseCard.AddComponent(); cardOutline.effectColor = new Color(1.00f, 0.85f, 0.10f, 0.55f); cardOutline.effectDistance = new Vector2(2f, -2f); CreateText("Pause_Title", pauseCard.transform, "ПАУЗА", 34, FontStyle.Bold, TextAnchor.MiddleCenter, new Color(1.00f, 0.85f, 0.10f, 1.0f), new Vector2(0.05f, 0.86f), new Vector2(0.95f, 0.97f), Vector2.zero, Vector2.zero); CreateImage("Pause_Divider", pauseCard.transform, new Color(1.00f, 0.85f, 0.10f, 0.40f), new Vector2(0.08f, 0.84f), new Vector2(0.92f, 0.845f), Vector2.zero, Vector2.zero); GameObject btnContainer = CreateEmptyRect("Buttons_Container", pauseCard.transform, new Vector2(0.08f, 0.05f), new Vector2(0.92f, 0.81f), Vector2.zero, Vector2.zero); VerticalLayoutGroup vLayout = btnContainer.AddComponent(); vLayout.spacing = 16f; vLayout.childAlignment = TextAnchor.MiddleCenter; vLayout.childControlWidth = true; vLayout.childControlHeight = false; vLayout.childForceExpandWidth = true; vLayout.childForceExpandHeight = false; // Кнопки меню паузы Button resumeBtn = CreateStyledButton("Btn_Resume", btnContainer.transform, "► ПРОДОЛЖИТЬ", yellowBtnNormal, yellowBtnHover, yellowBtnPress, blackBtnText, 62f, 20); Button settingsBtn = CreateStyledButton("Btn_Settings", btnContainer.transform, "⚙ НАСТРОЙКИ", yellowBtnNormal, yellowBtnHover, yellowBtnPress, blackBtnText, 62f, 20); Button restartBtn = CreateStyledButton("Btn_Restart", btnContainer.transform, "↺ ЗАНОВО", yellowBtnNormal, yellowBtnHover, yellowBtnPress, blackBtnText, 62f, 20); Button menuBtn = CreateStyledButton("Btn_MainMenu", btnContainer.transform, "⌂ ГЛАВНОЕ МЕНЮ", yellowBtnNormal, yellowBtnHover, yellowBtnPress, blackBtnText, 62f, 20); Button quitBtn = CreateStyledButton("Btn_Quit", btnContainer.transform, "✖ ВЫХОД ИЗ ИГРЫ", new Color(0.35f, 0.15f, 0.15f, 1.0f), new Color(0.50f, 0.20f, 0.20f, 1.0f), new Color(0.65f, 0.25f, 0.25f, 1.0f), Color.white, 62f, 20); // ========================================== // 2. ПАНЕЛЬ НАСТРОЕК (SettingsPanel) - ТОЧНО КАК В ГЛАВНОМ МЕНЮ // ========================================== GameObject settingsPanel = CreateEmptyRect("SettingsPanel", canvasGo.transform, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); CreateImage("Backdrop_Dim", settingsPanel.transform, new Color(0.0f, 0.0f, 0.0f, 0.92f), Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero); GameObject settingsCard = CreateImage("Settings_Card", settingsPanel.transform, new Color(0.04f, 0.04f, 0.04f, 0.98f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(920f, 740f), Vector2.zero); Outline panelOutline = settingsCard.AddComponent(); panelOutline.effectColor = new Color(1.00f, 0.85f, 0.10f, 0.55f); panelOutline.effectDistance = new Vector2(2f, -2f); CreateText("Settings_Header", settingsCard.transform, "НАСТРОЙКИ", 28, FontStyle.Bold, TextAnchor.MiddleCenter, new Color(1.00f, 0.85f, 0.10f, 1.0f), new Vector2(0.05f, 0.90f), new Vector2(0.95f, 0.98f), Vector2.zero, Vector2.zero); CreateImage("Settings_Divider", settingsCard.transform, new Color(1.00f, 0.85f, 0.10f, 0.40f), new Vector2(0.05f, 0.89f), new Vector2(0.95f, 0.895f), Vector2.zero, Vector2.zero); GameObject settingsList = CreateEmptyRect("Settings_List", settingsCard.transform, new Vector2(0.06f, 0.14f), new Vector2(0.94f, 0.87f), Vector2.zero, Vector2.zero); VerticalLayoutGroup settingsLayout = settingsList.AddComponent(); settingsLayout.spacing = 15f; settingsLayout.childAlignment = TextAnchor.UpperCenter; settingsLayout.childControlWidth = true; settingsLayout.childControlHeight = false; settingsLayout.childForceExpandWidth = true; settingsLayout.childForceExpandHeight = false; // --- Раздел: Звук --- CreateCategoryHeader("HEADER_AUDIO", settingsList.transform, "— ЗВУК И ЭХОЛОКАЦИЯ —"); var volumeRow = CreateSliderRow("Row_Volume", settingsList.transform, "Громкость звука", 0f, 1f, 1f, "%"); Slider volSlider = volumeRow.slider; Text volText = volumeRow.valueText; Toggle muteToggle = CreateToggleRow("Row_Mute", settingsList.transform, "Отключить звук (Mute)"); // --- Раздел: Графика --- CreateCategoryHeader("HEADER_GRAPHICS", settingsList.transform, "— ГРАФИКА —"); Dropdown qualityDropdown = CreateDropdownRow("Row_Quality", settingsList.transform, "Качество графики"); Toggle fullscreenToggle = CreateToggleRow("Row_Fullscreen", settingsList.transform, "Полноэкранный режим"); Dropdown resolutionDropdown = CreateDropdownRow("Row_Resolution", settingsList.transform, "Разрешение экрана"); // --- Раздел: Управление --- CreateCategoryHeader("HEADER_CONTROLS", settingsList.transform, "— УПРАВЛЕНИЕ —"); var sensRow = CreateSliderRow("Row_Sensitivity", settingsList.transform, "Чувствительность мыши", 0.2f, 3.0f, 1.0f, "x"); Slider sensSlider = sensRow.slider; Text sensText = sensRow.valueText; // Нижняя строка кнопок в панели настроек GameObject bottomButtonsRow = CreateEmptyRect("Settings_BottomButtons", settingsCard.transform, new Vector2(0.06f, 0.03f), new Vector2(0.94f, 0.12f), Vector2.zero, Vector2.zero); HorizontalLayoutGroup bottomLayout = bottomButtonsRow.AddComponent(); bottomLayout.spacing = 30f; bottomLayout.childAlignment = TextAnchor.MiddleCenter; bottomLayout.childControlWidth = true; bottomLayout.childControlHeight = true; bottomLayout.childForceExpandWidth = true; bottomLayout.childForceExpandHeight = true; Button resetBtn = CreateStyledButton("Button_ResetDefaults", bottomButtonsRow.transform, "Сброс", new Color(0.35f, 0.15f, 0.15f, 1.0f), new Color(0.50f, 0.20f, 0.20f, 1.0f), new Color(0.65f, 0.25f, 0.25f, 1.0f), Color.white, 50f, 18); Button backBtn = CreateStyledButton("Button_Back", bottomButtonsRow.transform, "Применить и выйти", yellowBtnNormal, yellowBtnHover, yellowBtnPress, blackBtnText, 50f, 18); // ========================================== // 3. ПРИВЯЗКА К СИСТЕМЕ PAUSEMENU // ========================================== pauseMenu.pauseMenuPanel = pausePanel; pauseMenu.settingsPanel = settingsPanel; pauseMenu.resumeButton = resumeBtn; pauseMenu.settingsButton = settingsBtn; pauseMenu.restartButton = restartBtn; pauseMenu.mainMenuButton = menuBtn; pauseMenu.quitButton = quitBtn; pauseMenu.backFromSettingsButton = backBtn; pauseMenu.resetDefaultsButton = resetBtn; // Привязываем обработчики через UnityEvent для отображения в Инспекторе UnityEditor.Events.UnityEventTools.AddPersistentListener(resumeBtn.onClick, pauseMenu.ResumeGame); UnityEditor.Events.UnityEventTools.AddPersistentListener(settingsBtn.onClick, pauseMenu.OpenSettings); UnityEditor.Events.UnityEventTools.AddPersistentListener(restartBtn.onClick, pauseMenu.RestartGame); UnityEditor.Events.UnityEventTools.AddPersistentListener(menuBtn.onClick, pauseMenu.ReturnToMainMenu); UnityEditor.Events.UnityEventTools.AddPersistentListener(quitBtn.onClick, pauseMenu.QuitGame); UnityEditor.Events.UnityEventTools.AddPersistentListener(backBtn.onClick, pauseMenu.CloseSettings); UnityEditor.Events.UnityEventTools.AddPersistentListener(resetBtn.onClick, pauseMenu.ResetToDefaults); pauseMenu.volumeSlider = volSlider; pauseMenu.volumeValueText = volText; pauseMenu.muteToggle = muteToggle; pauseMenu.qualityDropdown = qualityDropdown; pauseMenu.fullscreenToggle = fullscreenToggle; pauseMenu.resolutionDropdown = resolutionDropdown; pauseMenu.sensitivitySlider = sensSlider; pauseMenu.sensitivityValueText = sensText; pausePanel.SetActive(false); settingsPanel.SetActive(false); // Также гарантируем экран смерти DeathScreenBuilder.Build(); EditorSceneManager.MarkSceneDirty(gameplayScene); EditorSceneManager.SaveScene(gameplayScene); Debug.Log("[PauseMenuBuilder] PauseCanvas в стиле MainMenu успешно создан и сохранен в SampleScene.unity"); return "SUCCESS: PauseMenu rebuilt with separate Settings panel matching MainMenu style!"; } #region Хелперы UI private static GameObject CreateEmptyRect(string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition) { GameObject go = new GameObject(name, typeof(RectTransform)); go.transform.SetParent(parent, false); RectTransform rt = go.GetComponent(); rt.anchorMin = anchorMin; rt.anchorMax = anchorMax; rt.sizeDelta = sizeDelta; rt.anchoredPosition = anchoredPosition; return go; } private static GameObject CreateImage(string name, Transform parent, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition) { GameObject go = CreateEmptyRect(name, parent, anchorMin, anchorMax, sizeDelta, anchoredPosition); Image img = go.AddComponent(); img.color = color; return go; } private static GameObject CreateText(string name, Transform parent, string text, int fontSize, FontStyle style, TextAnchor alignment, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 anchoredPosition) { GameObject go = CreateEmptyRect(name, parent, anchorMin, anchorMax, sizeDelta, anchoredPosition); Text t = go.AddComponent(); t.font = standardFont; t.text = text; t.fontSize = fontSize; t.fontStyle = style; t.alignment = alignment; t.color = color; t.horizontalOverflow = HorizontalWrapMode.Overflow; t.verticalOverflow = VerticalWrapMode.Overflow; return go; } private static Button CreateStyledButton(string name, Transform parent, string label, Color normalColor, Color highlightedColor, Color pressedColor, Color textColor, float height, int fontSize) { GameObject btnObj = DefaultControls.CreateButton(uiResources); btnObj.name = name; btnObj.transform.SetParent(parent, false); RectTransform rt = btnObj.GetComponent(); if (rt != null) { rt.sizeDelta = new Vector2(rt.sizeDelta.x, height); } LayoutElement layout = btnObj.AddComponent(); layout.minHeight = height; layout.preferredHeight = height; Image img = btnObj.GetComponent(); img.color = normalColor; img.type = Image.Type.Sliced; Outline btnOutline = btnObj.AddComponent(); btnOutline.effectColor = new Color(1.00f, 0.95f, 0.60f, 0.65f); btnOutline.effectDistance = new Vector2(2f, -2f); Shadow btnShadow = btnObj.AddComponent(); btnShadow.effectColor = new Color(0.00f, 0.00f, 0.00f, 0.50f); btnShadow.effectDistance = new Vector2(2f, -2f); Button btn = btnObj.GetComponent