using System; using System.IO; using UnityEngine; using UnityEngine.SceneManagement; [DefaultExecutionOrder(-1000)] public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set; } public bool IsPaused { get; private set; } public event Action PauseStateChanged; public int world { get; private set; } = 1; public int stage { get; private set; } = 1; public int stagesByWorld { get; private set; } = 5; public int lives { get; private set; } = 3; public int coins { get; private set; } = 0; public GameObject playerObj; [SerializeField] private GameObject playerPrefab; [SerializeField] private string playerPrefabResourcePath = "Prefabs/Player"; private bool _shouldSpawnPlayer; private void OnEnable() => SceneManager.sceneLoaded += OnSceneLoaded; private void OnDisable() => SceneManager.sceneLoaded -= OnSceneLoaded; public event Action CoinsChanged; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void Bootstrap() { if (Instance == null) { var go = new GameObject(nameof(GameManager)); Instance = go.AddComponent(); DontDestroyOnLoad(go); } } private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } private void OnDestroy() { if (Instance == this) Instance = null; } //private void Start() //{ // //Application.targetFrameRate = 60; // //LoadScene("MainMenu", false); // //NewGame(); // if (SceneManager.GetActiveScene().name != "MainMenu") // { // TrySpawnPlayerForActiveScene(); // } //} private GameObject ResolvePlayerPrefab() { if (playerPrefab != null) return playerPrefab; var loaded = Resources.Load(playerPrefabResourcePath); if (loaded == null) { Debug.LogError( $"GameManager: playerPrefab is null. Resources.Load('{playerPrefabResourcePath}') вернул null. " + $"Ожидается файл: Assets/Resources/{playerPrefabResourcePath}.prefab (точное совпадение регистра)."); } return loaded; } public void NewGame() { lives = 3; coins = 0; CoinsChanged?.Invoke(coins); LoadLevel(1, 1); } public void GameOver() => LoadScene("MainMenu", false); public void LoadLevel(int world, int stage) { this.world = world; this.stage = stage; string sceneName = $"{world}-{stage}"; if (SceneInBuildSettingsExists(sceneName)) { LoadScene(sceneName); } else { print("WIN"); //NewGame(); LoadScene("MainMenu", false); } } public void LoadScene(string sceneName, bool useUI = true) { _shouldSpawnPlayer = true; SceneManager.LoadScene(sceneName); if (useUI) { SceneManager.LoadScene("Level UI", LoadSceneMode.Additive); } else _shouldSpawnPlayer = false; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { TrySpawnPlayerForActiveScene(); } private void TrySpawnPlayerForActiveScene() { if (!_shouldSpawnPlayer) return; var spawn = FindFirstObjectByType(); Vector3 pos = spawn ? spawn.transform.position : new Vector3(0, 1.3f, 0); Quaternion rot = spawn ? spawn.transform.rotation : Quaternion.identity; playerObj = GameObject.FindGameObjectWithTag("Player"); if (playerObj != null) Destroy(playerObj); var prefab = ResolvePlayerPrefab(); if (prefab == null) return; playerObj = Instantiate(prefab, pos, rot); SceneManager.MoveGameObjectToScene(playerObj, SceneManager.GetActiveScene()); } public void NextLevel() { if (stage >= stagesByWorld) LoadLevel(world + 1, 1); else LoadLevel(world, stage + 1); } public void ResetLevel() { lives--; //print($"Lives: {lives}"); if (lives > 0) LoadLevel(world, stage); else GameOver(); } public void AddCoin() { coins++; if (coins >= 100) { coins = 0; AddLife(); } CoinsChanged?.Invoke(coins); } public void SetPause(bool pause) { if (IsPaused == pause) return; IsPaused = pause; Time.timeScale = pause ? 0f : 1f; AudioListener.pause = pause; PauseStateChanged?.Invoke(IsPaused); } public void TogglePause() => SetPause(!IsPaused); public void AddLife() => lives++; private static bool SceneInBuildSettingsExists(string sceneName) { int count = SceneManager.sceneCountInBuildSettings; for (int i = 0; i < count; i++) { string path = SceneUtility.GetScenePathByBuildIndex(i); if (Path.GetFileNameWithoutExtension(path) == sceneName) return true; } return false; } }