581 lines
17 KiB
C#
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;
|
|
}
|
|
}
|
|
} |