using UnityEngine; using System.Collections; using UnityEngine.UI; using TMPro; using PrimeTween; using UnityEngine.SceneManagement; using Unity.Mathematics; using System; using log4net; using Managers; using Sequence = PrimeTween.Sequence; namespace SlimUI.ModernMenu { public class SlimUIMainMenu : MonoBehaviour { private static readonly ILog Log = LogManager.GetLogger(typeof(SlimUIMainMenu)); private Animator CameraObject; private event EventHandler CustomSceneLoaded; private GameManager GM; private ManageableAudio MainMenuMusic; // campaign button sub menu [Header("MENUS")] [Tooltip("The first list of buttons")] public GameObject firstMenu; [Tooltip("The Menu for when the PLAY button is clicked")] public GameObject playMenu; [Tooltip("The Menu for when the EXIT button is clicked")] public GameObject exitMenu; [Tooltip("Optional 4th Menu")] public GameObject extrasMenu; public enum Theme { custom1, custom2, custom3 }; [Header("THEME SETTINGS")] public Theme theme; private int themeIndex; public ThemedUIData themeController; [Header("PANELS")] [Tooltip("The UI Panel parenting all sub menus")] public GameObject mainCanvas; [Tooltip("The UI Panel parenting the settings")] public GameObject optionsCanvas; [Tooltip("The UI Panel that holds the CONTROLS window tab")] public GameObject PanelControls; [Tooltip("The UI Panel that holds the VIDEO window tab")] public GameObject PanelVideo; [Tooltip("The UI Panel that holds the GAME window tab")] public GameObject PanelGame; [Tooltip("The UI Panel that holds the KEY BINDINGS window tab")] public GameObject PanelKeyBindings; [Tooltip("The UI Sub-Panel under KEY BINDINGS for MOVEMENT")] public GameObject PanelMovement; [Tooltip("The UI Sub-Panel under KEY BINDINGS for COMBAT")] public GameObject PanelCombat; [Tooltip("The UI Sub-Panel under KEY BINDINGS for GENERAL")] public GameObject PanelGeneral; // highlights in settings screen [Header("SETTINGS SCREEN")] [Tooltip("Highlight Image for when GAME Tab is selected in Settings")] public GameObject lineGame; [Tooltip("Highlight Image for when VIDEO Tab is selected in Settings")] public GameObject lineVideo; [Tooltip("Highlight Image for when CONTROLS Tab is selected in Settings")] public GameObject lineControls; [Tooltip("Highlight Image for when KEY BINDINGS Tab is selected in Settings")] public GameObject lineKeyBindings; [Tooltip("Highlight Image for when MOVEMENT Sub-Tab is selected in KEY BINDINGS")] public GameObject lineMovement; [Tooltip("Highlight Image for when COMBAT Sub-Tab is selected in KEY BINDINGS")] public GameObject lineCombat; [Tooltip("Highlight Image for when GENERAL Sub-Tab is selected in KEY BINDINGS")] public GameObject lineGeneral; [Header("LOADING SCREEN")] public GameObject loadingMenu; [Tooltip("The loading bar Slider UI element in the Loading Screen")] public Slider loadingBar; public TMP_Text loadProgressText; public KeyCode userPromptKey; [Header("SFX")] [Tooltip("The GameObject holding the Audio Source component for the HOVER SOUND")] public AudioSource hoverSound; [Tooltip("The GameObject holding the Audio Source component for the AUDIO SLIDER")] public AudioSource sliderSound; [Tooltip("The GameObject holding the Audio Source component for the SWOOSH SOUND when switching to the Settings Screen")] public AudioSource swooshSound; void Awake() { SceneManager.activeSceneChanged += CameraOnSceneActive; } void Start() { GM = GameManager.G; CameraObject = transform.GetComponent(); playMenu.SetActive(false); exitMenu.SetActive(false); if (extrasMenu) extrasMenu.SetActive(false); firstMenu.SetActive(true); // Position1(); SetThemeColors(); MainMenuMusic = AudioManager.G.GetGlobalSound("main_menu_music", 1, false); MainMenuMusic.PlayAudio(true); } void SetThemeColors() { switch (theme) { case Theme.custom1: themeController.currentColor = themeController.custom1.graphic1; themeController.textColor = themeController.custom1.text1; themeIndex = 0; break; case Theme.custom2: themeController.currentColor = themeController.custom2.graphic2; themeController.textColor = themeController.custom2.text2; themeIndex = 1; break; case Theme.custom3: themeController.currentColor = themeController.custom3.graphic3; themeController.textColor = themeController.custom3.text3; themeIndex = 2; break; default: Debug.Log("Invalid theme selected."); break; } } public void PlayCampaign() { exitMenu.SetActive(false); if (extrasMenu) extrasMenu.SetActive(false); playMenu.SetActive(true); } public void PlayCampaignMobile() { exitMenu.SetActive(false); if (extrasMenu) extrasMenu.SetActive(false); playMenu.SetActive(true); } public void ReturnMenu() { playMenu.SetActive(false); if (extrasMenu) extrasMenu.SetActive(false); exitMenu.SetActive(false); } /// /// Currently starts loading a scene from the availabe scene enums, /// asynchronously. /// Before that it registers events which are triggered when the scene has loaded. /// Here it is the flying camera transition to the new scene and /// the match start routine in the GameManager. /// /// The scene id which will be loaded (see Scenes enum) public void LoadScene(int sceneId) { if (GM != null) { if (((Scenes)sceneId).ToString() == "Arena") { GM.SingleUseSceneLoadedMethodCaller(ArenaTransition, Scenes.Arena); } } StartCoroutine(LoadAsynchronously((Scenes)sceneId)); } /// /// Defines a delegate which animates a camera flight and /// gives it to the game manager to execute once the scene is loaded. /// /// The scene which when loaded triggers the event + /// delegate execution private void ArenaTransition(SceneLoadEventArgs args) { SceneManager.SetActiveScene(args.SceneRef); Log.Info("Camera will fly to scene: " + args.SceneRef.name); GameObject target = GameObject.Find("Match Camera"); if (target != null) { target.TryGetComponent(out Camera camera); target.TryGetComponent(out AudioListener listener); camera.enabled = false; listener.enabled = false; gameObject.TryGetComponent(out Camera oldCamera); gameObject.TryGetComponent(out AudioListener oldListener); gameObject.GetComponent().enabled = false; optionsCanvas.SetActive(false); // Camera flight tween with camera hand-off at the end. Sequence.Create() .Group(Tween.Position(gameObject.transform, target.transform.position, 2f)) .Group(Tween.Rotation(gameObject.transform, target.transform.rotation, 2f)) .ChainCallback(() => { oldCamera.enabled = false; oldListener.enabled = false; camera.enabled = true; listener.enabled = true; StartCoroutine(SwitchToIngameUI()); }); } else { Log.Error("Match Camera GameObject not found in any scene. Can't transition to match."); } } /// /// Defines a delegate which animates a camera flight and /// gives it to the game manager to execute once the scene is loaded. /// /// The scene which when loaded triggers the event + /// delegate execution public void MenuTransition(Transform cameraTransform) { Log.Info("Camera will fly to the main menu scene"); optionsCanvas.SetActive(false); if (gameObject.TryGetComponent(out Camera target)) { // Camera flight tween with camera hand-off at the end. Sequence.Create() .Group(Tween.Position(cameraTransform, target.transform.position, 2f)) .Group(Tween.Rotation(cameraTransform, target.transform.rotation, 2f)) .ChainCallback(() => { SceneManager.SetActiveScene(SceneManager.GetSceneByBuildIndex((int)Scenes.MainMenu)); optionsCanvas.SetActive(true); SceneManager.UnloadSceneAsync((int)Scenes.InGameUI); SceneManager.UnloadSceneAsync((int)Scenes.Arena); }); } else { Log.Error("Menu has no camera component."); } } /// /// Loads the Gameplay UI and after that unloads the Main Menu. /// Also Initiates the setup of the local match once the Gameplay UI is /// loaded. /// /// IEnumerator for async statemachine private IEnumerator SwitchToIngameUI() { MainMenuMusic.FadeOutAudio(2, true); AsyncOperation o = SceneManager.LoadSceneAsync((int)Scenes.InGameUI, LoadSceneMode.Additive); while (!o.isDone) { yield return false; } yield return new WaitForSeconds(0.1f); yield return StartCoroutine(GM.SetupLocalMatchFromMainMenu()); SceneManager.UnloadSceneAsync((int)Scenes.MainMenu); } public void DisablePlayCampaign() { playMenu.SetActive(false); } public void Position2() { DisablePlayCampaign(); CameraObject.SetFloat("Animate", 1); } public void Position1() { CameraObject.SetFloat("Animate", 0); } void DisablePanels() { PanelControls.SetActive(false); PanelVideo.SetActive(false); PanelGame.SetActive(false); PanelKeyBindings.SetActive(false); lineGame.SetActive(false); lineControls.SetActive(false); lineVideo.SetActive(false); lineKeyBindings.SetActive(false); PanelMovement.SetActive(false); lineMovement.SetActive(false); PanelCombat.SetActive(false); lineCombat.SetActive(false); PanelGeneral.SetActive(false); lineGeneral.SetActive(false); } public void GamePanel() { DisablePanels(); PanelGame.SetActive(true); lineGame.SetActive(true); } public void VideoPanel() { DisablePanels(); PanelVideo.SetActive(true); lineVideo.SetActive(true); } public void ControlsPanel() { DisablePanels(); PanelControls.SetActive(true); lineControls.SetActive(true); } public void KeyBindingsPanel() { DisablePanels(); MovementPanel(); PanelKeyBindings.SetActive(true); lineKeyBindings.SetActive(true); } public void MovementPanel() { DisablePanels(); PanelKeyBindings.SetActive(true); PanelMovement.SetActive(true); lineMovement.SetActive(true); } public void CombatPanel() { DisablePanels(); PanelKeyBindings.SetActive(true); PanelCombat.SetActive(true); lineCombat.SetActive(true); } public void GeneralPanel() { DisablePanels(); PanelKeyBindings.SetActive(true); PanelGeneral.SetActive(true); lineGeneral.SetActive(true); } public void PlayHover() { hoverSound.Play(); } public void PlaySFXHover() { sliderSound.Play(); } public void PlaySwoosh() { swooshSound.Play(); } // Are You Sure - Quit Panel Pop Up public void AreYouSure() { exitMenu.SetActive(true); if (extrasMenu) extrasMenu.SetActive(false); DisablePlayCampaign(); } public void AreYouSureMobile() { exitMenu.SetActive(true); if (extrasMenu) extrasMenu.SetActive(false); DisablePlayCampaign(); } public void ExtrasMenu() { playMenu.SetActive(false); if (extrasMenu) extrasMenu.SetActive(true); exitMenu.SetActive(false); } public void QuitGame() { #if UNITY_EDITOR UnityEditor.EditorApplication.isPlaying = false; #else Application.Quit(); #endif } // Load Bar syncing animation IEnumerator LoadAsynchronously(Scenes sceneEnum) { AsyncOperation operation = SceneManager.LoadSceneAsync((int)sceneEnum, LoadSceneMode.Additive); operation.allowSceneActivation = false; mainCanvas.SetActive(false); loadingMenu.SetActive(true); do { float progress = operation.progress; float normProgress = progress + 0.1f; loadingBar.value = normProgress; loadProgressText.text = "Loading " + math.round(normProgress * 100).ToString() + "%"; if (progress >= 0.85f) { yield return Tween.Delay(0.5f).ToYieldInstruction(); operation.allowSceneActivation = true; } yield return Tween.Delay(0.04f).ToYieldInstruction(); } while (!operation.isDone); } /// /// Enable the menu camera, when the main menu scene is set as active. /// /// Scene which was active before /// Newly active scene private void CameraOnSceneActive(Scene oldScene, Scene newScene) { if (newScene == SceneManager.GetSceneByBuildIndex((int)Scenes.MainMenu)) { if (gameObject.TryGetComponent(out Camera camera)) { camera.enabled = true; } if (gameObject.TryGetComponent(out AudioListener listener)) { listener.enabled = true; } } } private void OnDestroy() { SceneManager.activeSceneChanged -= CameraOnSceneActive; } } }