Zabiju je
This commit is contained in:
@@ -4,43 +4,53 @@ using Subsystems;
|
||||
using System.Collections;
|
||||
using System;
|
||||
using TMPro;
|
||||
/*
|
||||
GameManager - hlavní tøida pro správu hry
|
||||
GameManager_Network - subsystém pro správu komunikace se serverem
|
||||
GameManager_Game - subsystém pro správu logiky hry (sabotáže, tasky, atd.)
|
||||
GameManager_Map - subsystém pro správu mapy a prostøedí
|
||||
GameManager_Input - subsystém pro správu vstupu od hráèe
|
||||
GameManager_UI - subsystém pro správu uživatelského rozhraní
|
||||
GamaManager_Stats - subsystém pro správu statistik pro server
|
||||
*/
|
||||
using UnityEngine.SceneManagement;
|
||||
public class GameManager : MonoBehaviour
|
||||
{
|
||||
[Header("Subsystems")]
|
||||
protected GameManager_Network networkSubsystem;
|
||||
protected GameManager_UI uiSubsystem;
|
||||
protected GameManager_Map mapSubsystem;
|
||||
protected GameManager_Input inputSubsystem;
|
||||
// Singleton
|
||||
public static GameManager Instance { get; private set; }
|
||||
|
||||
protected GameClient gameClient;
|
||||
[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("UI Elements")]
|
||||
public Canvas JoinCreateLobby;
|
||||
public Canvas InLobby;
|
||||
public Canvas LoadingScreen;
|
||||
public Canvas GameScreen;
|
||||
[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")]
|
||||
public GameObject MapCenterPoint;
|
||||
// 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("GPS")]
|
||||
public GameObject Player;
|
||||
[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;
|
||||
@@ -49,100 +59,307 @@ public class GameManager : MonoBehaviour
|
||||
private GameManager_Network _secondNetwork;
|
||||
private GameManager_Network _thirdNetwork;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
DontDestroyOnLoad(this);
|
||||
if (displayName == null || displayName == "")
|
||||
{
|
||||
displayName = GenerateUsername();
|
||||
}
|
||||
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);
|
||||
_secondNetwork = new GameManager_Network(_secondClient, null);
|
||||
_thirdClient = new GameClient(GenerateUUID(), GenerateUsername());
|
||||
_thirdNetwork = new GameManager_Network(_thirdClient);
|
||||
|
||||
_secondNetwork.OpenConection();
|
||||
_thirdNetwork.OpenConection();
|
||||
_thirdNetwork = new GameManager_Network(_thirdClient, null);
|
||||
_secondNetwork.OpenConnection();
|
||||
_thirdNetwork.OpenConnection();
|
||||
}
|
||||
gameClient = new GameClient(GenerateUUID(), displayName);
|
||||
uiSubsystem = new GameManager_UI(gameClient, JoinCreateLobby, InLobby, LoadingScreen, GameScreen);
|
||||
networkSubsystem = new GameManager_Network(gameClient);
|
||||
mapSubsystem = new GameManager_Map(gameClient, MapCenterPoint, buildingSettings, pathwaySettings, areaSettings);
|
||||
inputSubsystem = new GameManager_Input(gameClient, Player, testMode);
|
||||
networkSubsystem.OpenConection();
|
||||
|
||||
networkSubsystem.OpenConnection();
|
||||
|
||||
// Load main menu after GameManager is ready
|
||||
if (!string.IsNullOrEmpty(firstMenuScene))
|
||||
SceneManager.LoadScene(firstMenuScene, LoadSceneMode.Single);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (gameClient.CurrentLobbyState != null)
|
||||
{
|
||||
uiSubsystem.UpdateLobbyUI();
|
||||
}
|
||||
try
|
||||
{
|
||||
if (gameClient.CurrentLobbyState.MapDataReady)
|
||||
{
|
||||
mapSubsystem.BuildMap();
|
||||
gameClient.CurrentLobbyState.MapDataReady = false;
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException ex) { }
|
||||
inputSubsystem.positionCheck();
|
||||
}
|
||||
|
||||
|
||||
protected string GenerateUUID()
|
||||
{
|
||||
string UUID = System.Guid.NewGuid().ToString();
|
||||
Debug.Log(UUID);
|
||||
return UUID;
|
||||
}
|
||||
protected string GenerateUsername()
|
||||
{
|
||||
string Username = UnityEngine.Random.Range(0,10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString() + UnityEngine.Random.Range(0, 10).ToString();
|
||||
Debug.Log(Username);
|
||||
return Username;
|
||||
}
|
||||
public void CreateLobbyButton()
|
||||
{
|
||||
networkSubsystem.CrateLobby(50.7727264, 15.0719876);
|
||||
// Tick the SDK dispatcher so callbacks fire on main thread
|
||||
gameClient?.Update();
|
||||
if (testMode)
|
||||
{
|
||||
StartCoroutine(ConnectTestClients());
|
||||
_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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// After Client.unity loads, re-bind all canvas/HUD references because
|
||||
/// those GameObjects don't exist in the Art menu scenes.
|
||||
/// </summary>
|
||||
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<Canvas>() : null;
|
||||
}
|
||||
|
||||
// ── Build HUD BEFORE BindClientScene so FindTMP/Find can locate new elements ──
|
||||
var inGameGO = FindGO("InGame");
|
||||
if (inGameGO != null)
|
||||
{
|
||||
var builder = inGameGO.GetComponent<InGameHUDBuilder>()
|
||||
?? inGameGO.AddComponent<InGameHUDBuilder>();
|
||||
builder.BuildNow();
|
||||
}
|
||||
|
||||
// ── Wire canvases (after HUD is built) ──
|
||||
uiSubsystem?.BindClientScene(
|
||||
FindCanvas(CanvasNameJoinCreate),
|
||||
FindCanvas(CanvasNameInLobby),
|
||||
FindCanvas(CanvasNameLoading),
|
||||
FindCanvas(CanvasNameGame));
|
||||
|
||||
// ── Wire map center point and player capsule ──
|
||||
var mapCenter = FindGO("MapCenterPoint");
|
||||
var player = FindGO("Capsule");
|
||||
mapSubsystem?.SetMapCenterPoint(mapCenter);
|
||||
inputSubsystem?.SetPlayerObject(player);
|
||||
|
||||
// ── Attach camera controller to Main Camera ──
|
||||
var mainCamGO = FindGO("Main Camera");
|
||||
if (mainCamGO != null)
|
||||
{
|
||||
var camCtrl = mainCamGO.GetComponent<MapCameraController>()
|
||||
?? mainCamGO.AddComponent<MapCameraController>();
|
||||
camCtrl.SetTarget(player);
|
||||
}
|
||||
|
||||
// If MapDataReady arrived before Client scene finished loading,
|
||||
// this will build the map now that scene references are valid.
|
||||
networkSubsystem?.OnClientSceneReady();
|
||||
}
|
||||
else if (scene.name == "create" || scene.name == "join loading")
|
||||
{
|
||||
// Lobby scene just loaded — ensure LobbyDisplayUI refreshes once
|
||||
// its Start() has run and registered itself (happens before Update).
|
||||
uiSubsystem?.NotifyLobbyChanged();
|
||||
}
|
||||
}
|
||||
public void JoinLobbyButton()
|
||||
|
||||
// ── Kill cooldown ─────────────────────────────────────────────────────────
|
||||
private float _killCooldownSeconds = 0f;
|
||||
private const float KillCooldownDuration = 20f;
|
||||
|
||||
private void UpdateKillCooldown()
|
||||
{
|
||||
TMP_InputField joinCode = JoinCreateLobby.transform.Find("InputCode").GetComponent<TMP_InputField>();
|
||||
if (joinCode.text != null && joinCode.text != "")
|
||||
if (_killCooldownSeconds > 0)
|
||||
{
|
||||
networkSubsystem.JoinLobby(joinCode.text);
|
||||
_killCooldownSeconds -= Time.deltaTime;
|
||||
uiSubsystem?.SetKillCooldownText($"Kill: {Mathf.CeilToInt(_killCooldownSeconds)}s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Join code is empty!");
|
||||
uiSubsystem?.SetKillCooldownText("");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by the ActionButton. Routes to kill / report / emergency / use-task
|
||||
/// depending on current proximity state.
|
||||
/// </summary>
|
||||
public void PerformAction()
|
||||
{
|
||||
if (uiSubsystem == null || uiSubsystem.IsPlayerDead) return;
|
||||
|
||||
bool isImpostor = gameClient?.MyRole == PlayerRole.Impostor;
|
||||
|
||||
// 1. Nearby task → USE
|
||||
var nearbyTask = taskSubsystem?.NearbyTask;
|
||||
if (nearbyTask != null && !isImpostor)
|
||||
{
|
||||
taskSubsystem.TriggerNearbyTask();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Nearby body → REPORT
|
||||
if (!uiSubsystem.IsCommsBlackout)
|
||||
{
|
||||
var nearbyBody = gameClient?.FindNearbyBody(5.0);
|
||||
if (nearbyBody != null)
|
||||
{
|
||||
gameClient.ReportBody(nearbyBody.BodyId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Near map centre → EMERGENCY
|
||||
if (gameClient?.CurrentLobbyState?.MapData != null)
|
||||
{
|
||||
double distToCenter = gameClient.MyPosition.DistanceTo(gameClient.CurrentLobbyState.MapData.Center);
|
||||
if (distToCenter <= 5.0)
|
||||
{
|
||||
gameClient.CallEmergencyMeeting();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Impostor kill
|
||||
if (isImpostor && _killCooldownSeconds <= 0)
|
||||
{
|
||||
var targetUuid = gameClient?.FindNearbyPlayer(5.0);
|
||||
if (!string.IsNullOrEmpty(targetUuid))
|
||||
{
|
||||
gameClient.Kill(targetUuid);
|
||||
_killCooldownSeconds = KillCooldownDuration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Called by Impostor sabotage buttons.</summary>
|
||||
public void StartSabotage(int typeIndex)
|
||||
{
|
||||
gameClient?.Send(new GeoSus.Client.StartSabotage { SabotageType = (SabotageType)typeIndex });
|
||||
}
|
||||
|
||||
/// <summary>Called by the meeting vote buttons. Pass null to skip.</summary>
|
||||
public void CastVote(string targetUuid)
|
||||
{
|
||||
gameClient?.Vote(targetUuid);
|
||||
}
|
||||
|
||||
protected string GenerateUUID()
|
||||
{
|
||||
return System.Guid.NewGuid().ToString();
|
||||
}
|
||||
protected string GenerateUsername()
|
||||
{
|
||||
return "Player" + UnityEngine.Random.Range(1000, 9999).ToString();
|
||||
}
|
||||
|
||||
// Called by HostLobbyUI
|
||||
public void CreateLobbyButton()
|
||||
{
|
||||
// Use current GPS position if available, else hardcoded fallback
|
||||
double lat = 50.7727264, lon = 15.0719876;
|
||||
if (inputSubsystem?.LastKnownPosition != null)
|
||||
{
|
||||
lat = inputSubsystem.LastKnownPosition.Value.Lat;
|
||||
lon = inputSubsystem.LastKnownPosition.Value.Lon;
|
||||
}
|
||||
networkSubsystem.CreateLobby(lat, lon, pendingRadius, pendingImpostorCount, pendingTaskCount);
|
||||
if (testMode) StartCoroutine(ConnectTestClients());
|
||||
}
|
||||
|
||||
// Called by JoinLobbyUI with the code from the input field
|
||||
public void JoinLobbyButton(string code)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(code))
|
||||
networkSubsystem.JoinLobby(code);
|
||||
else
|
||||
Debug.LogWarning("Join code is empty!");
|
||||
}
|
||||
|
||||
public void LeaveLobbyButton()
|
||||
{
|
||||
networkSubsystem.LeaveLobby();
|
||||
}
|
||||
|
||||
public void StartGameButton()
|
||||
{
|
||||
networkSubsystem.StartGame();
|
||||
}
|
||||
|
||||
void OnApplicationQuit()
|
||||
{
|
||||
gameClient.Disconnect();
|
||||
gameClient?.Disconnect();
|
||||
_secondClient?.Disconnect();
|
||||
_thirdClient?.Disconnect();
|
||||
_thirdClient?.Disconnect();
|
||||
}
|
||||
IEnumerator ConnectTestClients()
|
||||
{
|
||||
yield return new WaitForSeconds(2f);
|
||||
_secondNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
|
||||
_thirdNetwork.JoinLobby(gameClient.CurrentLobbyState.JoinCode);
|
||||
|
||||
IEnumerator ConnectTestClients()
|
||||
{
|
||||
// Wait until host lobby code exists
|
||||
float wait = 0f;
|
||||
while ((gameClient?.CurrentLobbyState == null || string.IsNullOrEmpty(gameClient.CurrentLobbyState.JoinCode)) && wait < 20f)
|
||||
{
|
||||
wait += 0.25f;
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
}
|
||||
|
||||
var joinCode = gameClient?.CurrentLobbyState?.JoinCode;
|
||||
if (string.IsNullOrEmpty(joinCode))
|
||||
{
|
||||
Debug.LogWarning("[TestMode] Could not join test clients: join code not available.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Wait until helper clients are connected and handshake-complete
|
||||
wait = 0f;
|
||||
while (((_secondClient == null || !_secondClient.IsReady) || (_thirdClient == null || !_thirdClient.IsReady)) && wait < 20f)
|
||||
{
|
||||
wait += 0.25f;
|
||||
yield return new WaitForSeconds(0.25f);
|
||||
}
|
||||
|
||||
if (_secondClient == null || _thirdClient == null || !_secondClient.IsReady || !_thirdClient.IsReady)
|
||||
{
|
||||
Debug.LogWarning("[TestMode] Helper clients are not ready, skipping auto-join.");
|
||||
yield break;
|
||||
}
|
||||
|
||||
_secondNetwork?.JoinLobby(joinCode);
|
||||
_thirdNetwork?.JoinLobby(joinCode);
|
||||
Debug.Log($"[TestMode] Helper clients joined lobby with code {joinCode}.");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user