using UnityEngine; using Core.Lifecycle; namespace Minigames.BirdPooper { /// /// Central game manager for Bird Pooper minigame. /// Manages game flow, UI, obstacle spawning, and reacts to player events. /// Singleton pattern for easy access. /// public class BirdPooperGameManager : ManagedBehaviour { private static BirdPooperGameManager _instance; public static BirdPooperGameManager Instance => _instance; [Header("References")] [SerializeField] private BirdPlayerController player; [SerializeField] private ObstacleSpawner obstacleSpawner; [SerializeField] private TargetSpawner targetSpawner; [SerializeField] private GameOverScreen gameOverScreen; [SerializeField] private GameObject poopPrefab; [Header("Game State")] private int targetsHit; private bool isGameOver; internal override void OnManagedAwake() { base.OnManagedAwake(); // Set singleton instance if (_instance != null && _instance != this) { Debug.LogWarning("[BirdPooperGameManager] Multiple instances detected! Destroying duplicate."); Destroy(gameObject); return; } _instance = this; // Validate references if (player == null) { Debug.LogError("[BirdPooperGameManager] Player reference not assigned!"); } if (obstacleSpawner == null) { Debug.LogError("[BirdPooperGameManager] ObstacleSpawner reference not assigned!"); } if (targetSpawner == null) { Debug.LogWarning("[BirdPooperGameManager] TargetSpawner reference not assigned! Targets will not spawn."); } if (gameOverScreen == null) { Debug.LogError("[BirdPooperGameManager] GameOverScreen reference not assigned!"); } else { // Hide game over screen on start gameOverScreen.gameObject.SetActive(false); } if (poopPrefab == null) { Debug.LogWarning("[BirdPooperGameManager] Poop prefab not assigned!"); } } internal override void OnManagedStart() { base.OnManagedStart(); // Initialize game state isGameOver = false; targetsHit = 0; // Subscribe to player events if (player != null) { player.OnPlayerDamaged.AddListener(HandlePlayerDamaged); Debug.Log("[BirdPooperGameManager] Subscribed to player damaged event"); } // Start obstacle spawning if (obstacleSpawner != null) { obstacleSpawner.StartSpawning(); Debug.Log("[BirdPooperGameManager] Started obstacle spawning"); } // Start target spawning if (targetSpawner != null) { targetSpawner.StartSpawning(); Debug.Log("[BirdPooperGameManager] Started target spawning"); } } internal override void OnManagedDestroy() { // Unsubscribe from player events if (player != null) { player.OnPlayerDamaged.RemoveListener(HandlePlayerDamaged); } // Clear singleton if (_instance == this) { _instance = null; } base.OnManagedDestroy(); } /// /// Called when player takes damage/dies. /// Shows game over screen. /// private void HandlePlayerDamaged() { if (isGameOver) return; isGameOver = true; Debug.Log($"[BirdPooperGameManager] Player damaged - Game Over! Targets Hit: {targetsHit}"); // Stop spawning obstacles if (obstacleSpawner != null) { obstacleSpawner.StopSpawning(); } // Stop spawning targets if (targetSpawner != null) { targetSpawner.StopSpawning(); } // Show game over screen if (gameOverScreen != null) { gameOverScreen.Show(); } else { Debug.LogError("[BirdPooperGameManager] GameOverScreen reference missing!"); } } /// /// Spawns a poop projectile at the player's current position. /// Called by UI button OnClick event. /// public void SpawnPoop() { if (isGameOver || player == null || poopPrefab == null) return; Vector3 spawnPosition = player.transform.position; Instantiate(poopPrefab, spawnPosition, Quaternion.identity); Debug.Log($"[BirdPooperGameManager] Spawned poop at {spawnPosition}"); } /// /// Called when a target is successfully hit by poop (Phase 5). /// public void OnTargetHit() { if (isGameOver) return; targetsHit++; Debug.Log($"[BirdPooperGameManager] Target Hit! Total: {targetsHit}"); } #region Public Accessors public bool IsGameOver => isGameOver; public int TargetsHit => targetsHit; #endregion } }