using UnityEngine;
using GeoSus.Client;
using Subsystems;
using System.Collections;
using System;
using TMPro;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
// Singleton
public static GameManager Instance { get; private set; }
[Header("Subsystems")]
public GameManager_Network networkSubsystem;
public GameManager_UI uiSubsystem;
public GameManager_Map mapSubsystem;
public GameManager_Input inputSubsystem;
public GameManager_Tasks taskSubsystem;
public GameClient gameClient;
[Header("Player Info")]
public string displayName;
[Header("Scene Management")]
[SerializeField] public string firstMenuScene = "main menu asi idk lol";
[Header("UI Elements (Client.unity)")]
// Canvas names in Client.unity — found at runtime in OnSceneLoaded
private const string CanvasNameJoinCreate = "LobbySelector";
private const string CanvasNameInLobby = "InLobby";
private const string CanvasNameLoading = "LoadingScreen";
private const string CanvasNameGame = "InGame";
[Header("Map")]
// MapCenterPoint and Player are in Client.unity — wired at runtime in OnSceneLoaded.
// buildingSettings/pathwaySettings/areaSettings must be assigned in SampleScene Inspector.
public BuildingSettings buildingSettings;
public PathwaySettings pathwaySettings;
public AreaSettings areaSettings;
[Header("Lobby Settings")]
public double pendingRadius = 500;
public int pendingImpostorCount = 1;
public int pendingTaskCount = 5;
[Header("Task Minigames (round-robin)")]
[SerializeField] public string[] minigameScenes = {
"MiniGame-Kabely",
"MiniGame-InsertKeys",
"MiniGame-FlappyBird",
"MiniGame-ThrowInHole"
};
[Header("Debug")]
public bool testMode = false;
private GameClient _secondClient;
private GameClient _thirdClient;
private GameManager_Network _secondNetwork;
private GameManager_Network _thirdNetwork;
void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(gameObject);
return;
}
Instance = this;
DontDestroyOnLoad(gameObject);
}
void Start()
{
if (string.IsNullOrEmpty(displayName))
displayName = PlayerPrefs.GetString("PlayerName", GenerateUsername());
gameClient = new GameClient(GenerateUUID(), displayName);
networkSubsystem = new GameManager_Network(gameClient, this);
mapSubsystem = new GameManager_Map(gameClient, null, buildingSettings, pathwaySettings, areaSettings);
uiSubsystem = new GameManager_UI(gameClient);
inputSubsystem = new GameManager_Input(gameClient, null, testMode);
taskSubsystem = new GameManager_Tasks(gameClient, minigameScenes, this);
if (testMode)
{
_secondClient = new GameClient(GenerateUUID(), GenerateUsername());
_secondNetwork = new GameManager_Network(_secondClient, null);
_thirdClient = new GameClient(GenerateUUID(), GenerateUsername());
_thirdNetwork = new GameManager_Network(_thirdClient, null);
_secondNetwork.OpenConnection();
_thirdNetwork.OpenConnection();
}
networkSubsystem.OpenConnection();
// Load main menu after GameManager is ready
if (!string.IsNullOrEmpty(firstMenuScene))
SceneManager.LoadScene(firstMenuScene, LoadSceneMode.Single);
}
private void Update()
{
// Tick the SDK dispatcher so callbacks fire on main thread
gameClient?.Update();
if (testMode)
{
_secondClient?.Update();
_thirdClient?.Update();
}
if (gameClient?.CurrentLobbyState != null)
{
uiSubsystem?.UpdateLobbyUI();
taskSubsystem?.UpdateProximity();
}
if (gameClient?.MyRole == PlayerRole.Impostor)
UpdateKillCooldown();
inputSubsystem?.positionCheck();
}
void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
///
/// After Client.unity loads, re-bind all canvas/HUD references because
/// those GameObjects don't exist in the Art menu scenes.
///
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (scene.name == "Client")
{
var roots = scene.GetRootGameObjects();
// Find a root or deep GameObject by name in the loaded scene
GameObject FindGO(string n) {
foreach (var go in roots) {
if (go.name == n) return go;
var found = go.transform.Find(n);
if (found != null) return found.gameObject;
}
return null;
}
Canvas FindCanvas(string n) {
var go = FindGO(n);
return go != null ? go.GetComponent