197 lines
5.2 KiB
C#
197 lines
5.2 KiB
C#
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<bool> 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<int> CoinsChanged;
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
|
private static void Bootstrap()
|
|
{
|
|
if (Instance == null)
|
|
{
|
|
var go = new GameObject(nameof(GameManager));
|
|
Instance = go.AddComponent<GameManager>();
|
|
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<GameObject>(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<PlayerSpawn>();
|
|
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;
|
|
}
|
|
}
|