Space-Smash-Out/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs

581 lines
17 KiB
C#

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 CameraAnimator;
private event EventHandler<SceneLoadEventArgs> CustomSceneLoaded;
private GameManager GM;
private ManageableAudio MainMenuMusic;
private int RuleIndex;
private int ArenaIndex;
// 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;
[Header("VFX")]
[Tooltip("Particle system for volumetric stars in the main menu")]
public GameObject starParticles;
void Awake()
{
if (gameObject.TryGetComponent(out Camera camera))
{
camera.enabled = false;
}
if (gameObject.TryGetComponent(out AudioListener listener))
{
listener.enabled = false;
}
SceneManager.activeSceneChanged += CameraOnSceneActive;
}
void Start()
{
GM = GameManager.G;
CameraAnimator = transform.GetComponent<Animator>();
CameraAnimator.Play("MenuCamIdle");
playMenu.SetActive(false);
exitMenu.SetActive(false);
if (extrasMenu) extrasMenu.SetActive(false);
firstMenu.SetActive(true);
// Position1();
SetThemeColors();
MainMenuMusic = AudioManager.G.GetGlobalSound("main_menu_music", 2, 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);
}
public void Local1v1MatchButtonClick()
{
LoadLocalMatch(3, 0, 0);
}
public void Local2v2MatchButtonClick()
{
LoadLocalMatch(3, 0, 1);
}
public void LocalFreeFlightButtonClick()
{
LoadLocalMatch(4, 1, 2);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="sceneId">The scene id which will be loaded (see Scenes enum)</param>
public void LoadLocalMatch(int sceneId, int ruleIndex, int arenaIndex)
{
RuleIndex = ruleIndex;
ArenaIndex = arenaIndex;
if (GM != null)
{
// Playable scenes come after ID 3 in the build order
if (sceneId >= 3)
{
GM.SingleUseSceneLoadedMethodCaller(LocalArenaTransition, (SceneEnum)sceneId);
}
}
LoadAsynchronously((SceneEnum)sceneId);
}
/// <summary>
/// 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.
/// </summary>
/// <param name="sceneId">The scene id which will be loaded (see Scenes enum)</param>
public void LoadOnlineScene(int sceneId)
{
if (GM != null)
{
if (sceneId >= 3)
{
GM.SingleUseSceneLoadedMethodCaller(OnlineArenaTransition, (SceneEnum)sceneId);
}
}
LoadAsynchronously((SceneEnum)sceneId);
}
/// <summary>
/// Defines a delegate which animates a camera flight and
/// gives it to the game manager to execute once the scene is loaded.
/// </summary>
/// <param name="sceneEnum">The scene which when loaded triggers the event +
/// delegate execution</param>
private void LocalArenaTransition(SceneLoadEventArgs args)
{
SceneManager.SetActiveScene(args.SceneRef);
GameManager.G.CurrentScene = args.SceneEnum;
Log.Info("Camera will fly to scene: " + args.SceneRef.name);
starParticles.SetActive(false);
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<Animator>().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(SwitchToLocalInGameScene());
});
}
else
{
Log.Error("Match Camera GameObject not found in any scene. Can't transition to match.");
}
}
/// <summary>
/// Defines a delegate which animates a camera flight and
/// gives it to the game manager to execute once the scene is loaded.
/// </summary>
/// <param name="sceneEnum">The scene which when loaded triggers the event +
/// delegate execution</param>
private void OnlineArenaTransition(SceneLoadEventArgs args)
{
SceneManager.SetActiveScene(args.SceneRef);
GameManager.G.CurrentScene = args.SceneEnum;
Log.Info("Camera will fly to scene: " + args.SceneRef.name);
starParticles.SetActive(false);
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<Animator>().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(SwitchToOnlineInGameScene());
});
}
else
{
Log.Error("Match Camera GameObject not found in any scene. Can't transition to match.");
}
}
/// <summary>
/// Defines a delegate which animates a camera flight and
/// gives it to the game manager to execute once the scene is loaded.
/// </summary>
/// <param name="cameraTransform">The camera which will fly the transition </param>
/// <param name="unloadScene">The scene which is unloaded after the transition</param>
public void MenuTransition(Transform cameraTransform, SceneEnum unloadScene)
{
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)SceneEnum.MainMenu));
optionsCanvas.SetActive(true);
SceneManager.UnloadSceneAsync((int)SceneEnum.InGameUI);
SceneManager.UnloadSceneAsync((int)unloadScene);
});
}
else
{
Log.Error("Menu has no camera component.");
}
}
/// <summary>
/// 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.
/// </summary>
/// <returns>IEnumerator for async statemachine</returns>
private IEnumerator SwitchToLocalInGameScene()
{
MainMenuMusic.FadeOutAudio(2, true);
AsyncOperation o = SceneManager.LoadSceneAsync((int)SceneEnum.InGameUI,
LoadSceneMode.Additive);
while (!o.isDone)
{
yield return false;
}
yield return new WaitForSeconds(0.1f);
yield return StartCoroutine(GM.SetupLocalMatchFromMainMenu(RuleIndex, ArenaIndex));
SceneManager.UnloadSceneAsync((int)SceneEnum.MainMenu);
}
/// <summary>
/// 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.
/// </summary>
/// <returns>IEnumerator for async statemachine</returns>
private IEnumerator SwitchToOnlineInGameScene()
{
MainMenuMusic.FadeOutAudio(2, true);
AsyncOperation o = SceneManager.LoadSceneAsync((int)SceneEnum.InGameUI,
LoadSceneMode.Additive);
while (!o.isDone)
{
yield return false;
}
yield return new WaitForSeconds(0.1f);
yield return StartCoroutine(GM.SetupOnlineMatchFromMainMenu());
SceneManager.UnloadSceneAsync((int)SceneEnum.MainMenu);
}
public void DisablePlayCampaign()
{
playMenu.SetActive(false);
}
public void Position3()
{
if (!SceneManager.GetSceneByName("OnlineLobby").isLoaded)
{
SceneManager.LoadScene("OnlineLobby", LoadSceneMode.Additive);
}
DisablePlayCampaign();
CameraAnimator.Play("FlyToLobby");
}
public void Position2()
{
DisablePlayCampaign();
CameraAnimator.Play("FlyToSettings");
}
public void Position1()
{
CameraAnimator.SetTrigger("BackToIdleTrigger");
}
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
async void LoadAsynchronously(SceneEnum 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)
{
await Tween.Delay(0.5f);
operation.allowSceneActivation = true;
}
await Tween.Delay(0.04f);
}
while (!operation.isDone);
}
/// <summary>
/// Enable the menu camera, when the main menu scene is set as active.
/// </summary>
/// <param name="oldScene">Scene which was active before</param>
/// <param name="newScene">Newly active scene</param>
private void CameraOnSceneActive(Scene oldScene, Scene newScene)
{
if (newScene == SceneManager.GetSceneByBuildIndex((int)SceneEnum.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;
}
}
}