194 lines
No EOL
6.4 KiB
C#
194 lines
No EOL
6.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
/// <summary>
|
|
/// class to handles overall game ui state and transitions
|
|
/// </summary>
|
|
public class UIManager : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// enum for available menus in the game, for use with <c>ShowMenu()</c>
|
|
/// </summary>
|
|
public enum DisplayState
|
|
{
|
|
UnassociatedState,
|
|
DefaultView,
|
|
GameView,
|
|
ResultsView,
|
|
LeaderboardView,
|
|
AccountView
|
|
}
|
|
|
|
/// <summary>
|
|
/// singleton pattern: define instance field for accessing the singleton elsewhere
|
|
/// </summary>
|
|
public static UIManager Instance;
|
|
|
|
/// <summary>
|
|
/// the current display state of the game
|
|
/// </summary>
|
|
[SerializeField] private DisplayState state = DisplayState.UnassociatedState;
|
|
|
|
/// <summary>
|
|
/// list of callbacks to invoke when the display state changes
|
|
/// </summary>
|
|
private readonly List<Action<DisplayState, DisplayState>> _onDisplayStateChangeCallbacks = new();
|
|
|
|
/// <summary>
|
|
/// the visual element object for game ui
|
|
/// </summary>
|
|
public VisualElement UI;
|
|
|
|
/// <summary>
|
|
/// enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances
|
|
/// </summary>
|
|
private void Awake()
|
|
{
|
|
// check if instance hasn't been set yet
|
|
if (Instance == null)
|
|
{
|
|
Debug.Log("awake as singleton instance, setting self as the forever-alive instance");
|
|
Instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
// check if instance is already set and it's not this instance
|
|
else if (Instance != null && Instance != this)
|
|
{
|
|
Debug.Log("awake as non-singleton instance, destroying self");
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// modify state of initial variables
|
|
/// </summary>
|
|
private void Start()
|
|
{
|
|
SetDisplayState(DisplayState.DefaultView);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
var gameplay = GameManager.Instance.Gameplay;
|
|
if (gameplay == null) return;
|
|
if (gameplay.Round >= 1) gameplay.Update();
|
|
}
|
|
|
|
/// <summary>
|
|
/// initialise variables and register callbacks
|
|
/// </summary>
|
|
private void OnEnable()
|
|
{
|
|
UI = GetComponent<UIDocument>().rootVisualElement;
|
|
}
|
|
|
|
/// <summary>
|
|
/// function to register a callback to be invoked when the display state changes
|
|
/// </summary>
|
|
/// <param name="callback">
|
|
/// callback function that takes two <c>DisplayState</c> parameters:
|
|
/// </param>
|
|
public void RegisterOnDisplayStateChangeCallback(Action<DisplayState, DisplayState> callback)
|
|
{
|
|
_onDisplayStateChangeCallbacks.Add(callback);
|
|
}
|
|
|
|
private void FireOnDisplayStateChange(DisplayState oldState, DisplayState newState)
|
|
{
|
|
foreach (var callback in _onDisplayStateChangeCallbacks)
|
|
try
|
|
{
|
|
callback.Invoke(oldState, newState);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"error invoking OnSignOutCallback: {e.Message}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// function to show a menu based on the enum passed,
|
|
/// and any other necessary actions
|
|
/// </summary>
|
|
/// <param name="newDisplayState">the game menu to show</param>
|
|
public void SetDisplayState(DisplayState newDisplayState)
|
|
{
|
|
// if the new state is the same as the current state, do nothing
|
|
if (state == newDisplayState)
|
|
{
|
|
Debug.Log($"staying at {state} (illogical transition)");
|
|
return;
|
|
}
|
|
|
|
Debug.Log($"switching from {state} to {newDisplayState}");
|
|
|
|
var defaultView = UI.Q<VisualElement>("DefaultView");
|
|
var gameView = UI.Q<VisualElement>("GameView");
|
|
var resultsView = UI.Q<VisualElement>("ResultsView");
|
|
var leaderboardView = UI.Q<VisualElement>("LeaderboardView");
|
|
var accountView = UI.Q<VisualElement>("AccountView");
|
|
|
|
defaultView.style.display = newDisplayState switch
|
|
{
|
|
DisplayState.DefaultView => DisplayStyle.Flex,
|
|
_ => DisplayStyle.None
|
|
};
|
|
|
|
gameView.style.display = newDisplayState switch
|
|
{
|
|
DisplayState.GameView => DisplayStyle.Flex,
|
|
_ => DisplayStyle.None
|
|
};
|
|
|
|
resultsView.style.display = newDisplayState switch
|
|
{
|
|
DisplayState.ResultsView => DisplayStyle.Flex,
|
|
_ => DisplayStyle.None
|
|
};
|
|
|
|
leaderboardView.style.display = newDisplayState switch
|
|
{
|
|
DisplayState.LeaderboardView => DisplayStyle.Flex,
|
|
_ => DisplayStyle.None
|
|
};
|
|
|
|
accountView.style.display = newDisplayState switch
|
|
{
|
|
DisplayState.AccountView => DisplayStyle.Flex,
|
|
_ => DisplayStyle.None
|
|
};
|
|
|
|
if (newDisplayState == DisplayState.GameView)
|
|
{
|
|
// if we're in the game view, everything except the account section/panel thing
|
|
UI.Q<Button>("PlayButton").style.display = DisplayStyle.None;
|
|
UI.Q<Button>("LeaderboardButton").style.display = DisplayStyle.None;
|
|
UI.Q<Button>("AccountButton").style.display = DisplayStyle.None;
|
|
UI.Q<VisualElement>("AccountSection").style.display = DisplayStyle.Flex;
|
|
UI.Q<VisualElement>("ConnectionStatus").style.display = DisplayStyle.None;
|
|
|
|
// start the game
|
|
GameManager.Instance.Gameplay.StartGame();
|
|
}
|
|
else
|
|
{
|
|
// if we're not in the game view, show everything!
|
|
UI.Q<Button>("PlayButton").style.display = DisplayStyle.Flex;
|
|
UI.Q<Button>("LeaderboardButton").style.display =
|
|
GameManager.Instance.Backend.Status == Backend.FirebaseConnectionStatus.Connected
|
|
? DisplayStyle.Flex
|
|
: DisplayStyle.None;
|
|
UI.Q<Button>("AccountButton").style.display =
|
|
GameManager.Instance.Backend.Status == Backend.FirebaseConnectionStatus.Connected
|
|
? DisplayStyle.Flex
|
|
: DisplayStyle.None;
|
|
UI.Q<VisualElement>("AccountSection").style.display = DisplayStyle.Flex;
|
|
UI.Q<VisualElement>("ConnectionStatus").style.display = DisplayStyle.Flex;
|
|
}
|
|
|
|
FireOnDisplayStateChange(state, newDisplayState);
|
|
state = newDisplayState;
|
|
}
|
|
} |