using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UIElements; /// /// singleton for a single source of truth game state and flow management /// public class GameManager : MonoBehaviour { /// /// singleton pattern: define instance field for accessing the singleton elsewhere /// public static GameManager Instance; /// /// ui manager object for handling ui state and flow /// public UIManager ui; /// /// list of callbacks to call when the local player data changes /// private readonly List> _onLocalPlayerDataChangeCallbacks = new(); /// /// the local player data object for storing player data /// private LocalPlayerData _data; /// /// backend object for handling communication with the firebase backend /// public Backend Backend; /// /// read-only property for accessing the local player data outside this class /// public LocalPlayerData Data => _data; /// /// enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances /// 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); } } /// /// start modifying state /// private void Start() { Debug.Log("GameManager starts here"); _data.LoadFromTheWorld(FireLocalPlayerDataChangeCallbacks); } /// /// initialise variables and ui elements /// private void OnEnable() { ui = UIManager.Instance; // load the local player data and refresh the ui _data = new LocalPlayerData(); Backend = new Backend(); Backend.Initialise(status => { Debug.Log("initialised backend, setting connection status text"); ui.UI.Q