Space-Smash-Out/Assets/SlimUI/Modern Menu 1/Scripts/Managers/SlimUIMainMenu.cs
Jakob Feldmann 64162cb4a1 feat: whole project restructuring
This can be seen as the initial state of the project after the released demo.

The changes include:
- New ship models
- Singleton manager structure to keep project scaleable in the future
     - Managing players, their settings, character choices, statistics, match setups, controls etc. in a separate decoupled scene
- Main menu with transitions to the arena scene
- Beginnings of a custom audio solution
- Logging with Log4Net

It is really a complete overhaul of the projects structure and management.
2024-04-01 23:06:39 +02:00

393 lines
11 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 CameraObject;
private event EventHandler<SceneLoadEventArgs> CustomSceneLoaded;
private GameManager GM;
// 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("Options")]
// public bool flyCameraLoadTransition = true;
void Start()
{
GM = GameManager.G;
CameraObject = transform.GetComponent<Animator>();
playMenu.SetActive(false);
exitMenu.SetActive(false);
if (extrasMenu) extrasMenu.SetActive(false);
firstMenu.SetActive(true);
// Position1();
SetThemeColors();
}
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);
}
/// <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 LoadScene(int sceneId)
{
if (GameManager.G != null)
{
if (((Scenes)sceneId).ToString() == "Arena")
{
GM.SingleUseSceneLoadedMethodCaller(ArenaTransition, Scenes.Arena);
}
}
optionsCanvas.SetActive(false);
StartCoroutine(LoadAsynchronously((Scenes)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 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<Animator>().enabled = 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.");
}
}
/// <summary>
/// Loads the Gameplay UI and unloads the Main Menu once thats loaded.
/// Also Initiates the setup of the local match once the Gameplay UI is
/// loaded.
/// </summary>
/// <returns></returns>
private IEnumerator SwitchToIngameUI()
{
AsyncOperation o = SceneManager.LoadSceneAsync((int)Scenes.GameplayUserInterface,
LoadSceneMode.Additive);
while (!o.isDone)
{
yield return false;
}
yield return new WaitForSeconds(0.1f);
yield return StartCoroutine(GM.SetupLocalMatchFromMainMenu());
SceneManager.UnloadSceneAsync((int)Scenes.MenuUserInterface);
}
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);
}
}
}