From 31040fcff472c0ef4fa05a083d85abb3b49bcd49 Mon Sep 17 00:00:00 2001 From: Paulius Dervinis Date: Tue, 7 Apr 2026 08:40:18 +0300 Subject: [PATCH 01/10] rework scene menu scripts --- .../Tests/Core Platform Menu/Escape Menu.cs | 80 -- .../Core Platform Menu/ReturnToMenuOverlay.cs | 277 +++++++ .../Tests/Core Platform Menu/Scene Loader.cs | 20 - .../QA/Tests/Core Platform Menu/SceneMenu.cs | 700 ++++++++++++++++++ Assets/Tools/AddScenesToBuild.cs | 187 +++-- 5 files changed, 1094 insertions(+), 170 deletions(-) delete mode 100644 Assets/QA/Tests/Core Platform Menu/Escape Menu.cs create mode 100644 Assets/QA/Tests/Core Platform Menu/ReturnToMenuOverlay.cs delete mode 100644 Assets/QA/Tests/Core Platform Menu/Scene Loader.cs create mode 100644 Assets/QA/Tests/Core Platform Menu/SceneMenu.cs diff --git a/Assets/QA/Tests/Core Platform Menu/Escape Menu.cs b/Assets/QA/Tests/Core Platform Menu/Escape Menu.cs deleted file mode 100644 index 896518b315..0000000000 --- a/Assets/QA/Tests/Core Platform Menu/Escape Menu.cs +++ /dev/null @@ -1,80 +0,0 @@ -using UnityEngine; -using UnityEngine.InputSystem; -using UnityEngine.SceneManagement; - -public class EscapeMenu : MonoBehaviour -{ - public InputAction openMenu; - private GameObject menuObject; - private bool isMenuOpened; - private Scene currentScene; - - public void Start() - { - menuObject = GameObject.Find("Escape Menu"); - menuObject.SetActive(false); - currentScene = SceneManager.GetActiveScene(); - - // Assign a callback for the "OpenMenu" action. - openMenu.performed += ctx => { OnEsc(ctx); }; - } - - public void OnEsc(InputAction.CallbackContext context) - { - isMenuOpened = !isMenuOpened; - - if (isMenuOpened) - { - DeactivateScene(currentScene); - ActivateMenu(); - } - else - { - ActivateScene(currentScene); - DeactivateMenu(); - } - } - - public void ActivateMenu() - { - menuObject.SetActive(true); - } - - public void DeactivateMenu() - { - menuObject.SetActive(false); - } - - public void ActivateScene(Scene scene) - { - GameObject[] rootObjects = scene.GetRootGameObjects(); - foreach (GameObject obj in rootObjects) - { - obj.SetActive(true); - } - } - - public void DeactivateScene(Scene scene) - { - GameObject[] rootObjects = scene.GetRootGameObjects(); - foreach (GameObject obj in rootObjects) - { - obj.SetActive(false); - } - } - - public void OnUIButtonPress() - { - SceneManager.LoadScene("Core Platforms Menu"); - } - - public void OnEnable() - { - openMenu.Enable(); - } - - public void OnDisable() - { - openMenu.Disable(); - } -} diff --git a/Assets/QA/Tests/Core Platform Menu/ReturnToMenuOverlay.cs b/Assets/QA/Tests/Core Platform Menu/ReturnToMenuOverlay.cs new file mode 100644 index 0000000000..9e816ce089 --- /dev/null +++ b/Assets/QA/Tests/Core Platform Menu/ReturnToMenuOverlay.cs @@ -0,0 +1,277 @@ +using TMPro; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.InputSystem; +using UnityEngine.InputSystem.UI; +using UnityEngine.SceneManagement; +using UnityEngine.UI; + +/// +/// Persistent floating overlay that lets the player return to the main menu (build +/// index 0) from any scene. Created automatically by when +/// a scene is loaded and destroys itself when returning to the menu. +/// +public class ReturnToMenuOverlay : MonoBehaviour +{ + static ReturnToMenuOverlay s_Instance; + + InputAction m_BackAction; + GameObject m_ConfirmPanel; + Canvas m_Canvas; + bool m_PanelVisible; + + static readonly Color kOverlay = new Color(0f, 0f, 0f, 0.7f); + static readonly Color kBtnNorm = new Color32(42, 42, 56, 230); + static readonly Color kBtnHover = new Color32(60, 70, 100, 240); + static readonly Color kPrimary = new Color32(80, 140, 255, 255); + static readonly Color kText = new Color32(230, 230, 240, 255); + static readonly Color kTextDim = new Color32(160, 160, 180, 255); + + public static void Show() + { + if (s_Instance != null) return; + var go = new GameObject("[ReturnToMenuOverlay]"); + DontDestroyOnLoad(go); + s_Instance = go.AddComponent(); + } + + public static void Hide() + { + if (s_Instance == null) return; + Destroy(s_Instance.gameObject); + s_Instance = null; + } + + void Awake() + { + BuildUI(); + SetupInput(); + SceneManager.sceneLoaded += OnSceneLoaded; + } + + void OnDestroy() + { + SceneManager.sceneLoaded -= OnSceneLoaded; + m_BackAction?.Dispose(); + if (s_Instance == this) s_Instance = null; + } + + void OnSceneLoaded(Scene scene, LoadSceneMode mode) + { + if (scene.buildIndex == 0) + { + Hide(); + return; + } + EnsureEventSystem(); + SetPanelVisible(false); + } + + #region Input + + void SetupInput() + { + m_BackAction = new InputAction("BackToMenu", InputActionType.Button); + m_BackAction.AddBinding("/escape"); + m_BackAction.AddBinding("/select"); + m_BackAction.performed += _ => TogglePanel(); + m_BackAction.Enable(); + } + + void TogglePanel() + { + SetPanelVisible(!m_PanelVisible); + } + + void SetPanelVisible(bool visible) + { + m_PanelVisible = visible; + if (m_ConfirmPanel != null) + m_ConfirmPanel.SetActive(visible); + } + + #endregion + + #region UI + + void BuildUI() + { + // Canvas + m_Canvas = gameObject.AddComponent(); + m_Canvas.renderMode = RenderMode.ScreenSpaceOverlay; + m_Canvas.sortingOrder = 999; + + var scaler = gameObject.AddComponent(); + scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + scaler.referenceResolution = new Vector2(1920, 1080); + scaler.matchWidthOrHeight = 0.5f; + + gameObject.AddComponent(); + + BuildMenuButton(); + BuildConfirmPanel(); + } + + void BuildMenuButton() + { + var go = new GameObject("MenuBtn", typeof(RectTransform)); + go.transform.SetParent(transform, false); + var img = go.AddComponent(); + img.color = kBtnNorm; + + var rt = go.GetComponent(); + rt.anchorMin = new Vector2(0, 1); + rt.anchorMax = new Vector2(0, 1); + rt.pivot = new Vector2(0, 1); + rt.anchoredPosition = new Vector2(16, -16); + rt.sizeDelta = new Vector2(120, 44); + + var btn = go.AddComponent