using UnityEngine; /// /// Central game manager that controls game state, timer, score, and puck in play status. /// public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set; } [Header("Game Settings")] [SerializeField] private float periodDuration = 1200f; // 20:00 in seconds [SerializeField] private int totalPeriods = 3; [Header("Game State")] private int homeScore = 0; private int awayScore = 0; private int currentPeriod = 1; private float timeRemaining = 1200f; // Start at 20:00 private bool isPuckInPlay = false; private bool isGameRunning = false; public bool IsPuckInPlay => isPuckInPlay; public bool IsGameRunning => isGameRunning; public int HomeScore => homeScore; public int AwayScore => awayScore; public int CurrentPeriod => currentPeriod; public float TimeRemaining => timeRemaining; // Events for UI updates public delegate void ScoreChangedHandler(int homeScore, int awayScore); public event ScoreChangedHandler OnScoreChanged; public delegate void TimeChangedHandler(float timeRemaining); public event TimeChangedHandler OnTimeChanged; public delegate void PeriodChangedHandler(int period); public event PeriodChangedHandler OnPeriodChanged; public delegate void PuckInPlayChangedHandler(bool inPlay); public event PuckInPlayChangedHandler OnPuckInPlayChanged; void Awake() { // Singleton pattern if (Instance == null) { Instance = this; } else { Destroy(gameObject); return; } } void Start() { timeRemaining = periodDuration; StartGame(); Debug.Log("Game started. All players frozen by default. Press F to start faceoff."); } void Update() { if (isGameRunning && isPuckInPlay && timeRemaining > 0) { timeRemaining -= Time.deltaTime; if (timeRemaining <= 0) { timeRemaining = 0; EndPeriod(); } OnTimeChanged?.Invoke(timeRemaining); } } public void StartGame() { isGameRunning = true; currentPeriod = 1; timeRemaining = periodDuration; homeScore = 0; awayScore = 0; OnScoreChanged?.Invoke(homeScore, awayScore); OnTimeChanged?.Invoke(timeRemaining); OnPeriodChanged?.Invoke(currentPeriod); Debug.Log("Game Started!"); } public void SetPuckInPlay(bool inPlay) { if (isPuckInPlay != inPlay) { isPuckInPlay = inPlay; OnPuckInPlayChanged?.Invoke(isPuckInPlay); Debug.Log($"Puck in play: {isPuckInPlay}"); } } public void AddHomeScore(int points = 1) { homeScore += points; OnScoreChanged?.Invoke(homeScore, awayScore); Debug.Log($"Home Team scores! {homeScore} - {awayScore}"); // Stop play after goal SetPuckInPlay(false); } public void AddAwayScore(int points = 1) { awayScore += points; OnScoreChanged?.Invoke(homeScore, awayScore); Debug.Log($"Away Team scores! {homeScore} - {awayScore}"); // Stop play after goal SetPuckInPlay(false); } private void EndPeriod() { SetPuckInPlay(false); isGameRunning = false; Debug.Log($"End of Period {currentPeriod}"); if (currentPeriod < totalPeriods) { // Start next period currentPeriod++; timeRemaining = periodDuration; OnPeriodChanged?.Invoke(currentPeriod); OnTimeChanged?.Invoke(timeRemaining); // Game will resume after faceoff isGameRunning = true; } else { EndGame(); } } private void EndGame() { Debug.Log($"Game Over! Final Score: {homeScore} - {awayScore}"); if (homeScore > awayScore) { Debug.Log("Home Team Wins!"); } else if (awayScore > homeScore) { Debug.Log("Away Team Wins!"); } else { Debug.Log("Game is tied!"); } } public void PauseGame() { isGameRunning = false; } public void ResumeGame() { isGameRunning = true; } public string GetFormattedTime() { int minutes = Mathf.FloorToInt(timeRemaining / 60f); int seconds = Mathf.FloorToInt(timeRemaining % 60f); return $"{minutes:00}:{seconds:00}"; } }