using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; using UnityEngine.Events; using UnityEngine.SceneManagement; public class GameStateChangedEvent : UnityEvent { } public enum GameState { Menu, Play, GameOver, GameOverMenu } public class GameStateManager : PersistentManager { private bool isLoading; private GameState gameState = GameState.Menu; public GameState GameState { get { return gameState; } } [SerializeField] private Image TransitionImage; private const float FADE_DURATION = 0.5f; public GameStateChangedEvent OnGameStateChangedEvent = new GameStateChangedEvent(); public GameState InitialState; protected override void Awake() { if(GameStateManager.Instance != null) { Destroy(this.gameObject); } else { base.Awake(); SetGameState(InitialState); } } private IEnumerator FadeCanvasToBlackCoroutine() { if(TransitionImage != null) { float x = 0.0f; while(x < 1.0f) { x += ((1.0f / FADE_DURATION) * Time.deltaTime); if(x > 1.0f) { x = 1.0f; } Color c = TransitionImage.color; c.a = x; TransitionImage.color = c; yield return new WaitForEndOfFrame(); } } } private IEnumerator FadeCanvasToTransparentCoroutine() { if(TransitionImage != null) { float x = 0.0f; while(x < 1.0f) { x += ((1.0f / FADE_DURATION) * Time.deltaTime); if(x > 1.0f) { x = 1.0f; } Color c = TransitionImage.color; c.a = x * -1.0f; TransitionImage.color = c; yield return new WaitForEndOfFrame(); } } } private IEnumerator loadGameSceneCoroutine() { StartCoroutine(FadeCanvasToBlackCoroutine()); yield return new WaitForSeconds(FADE_DURATION); AsyncOperation asyncOperation = SceneManager.LoadSceneAsync("test"); while(!asyncOperation.isDone) { yield return new WaitForSeconds(0.1f); } yield return new WaitForSeconds(1.0f); this.updateGameStateAndFireEvents(GameState.Play); StartCoroutine(FadeCanvasToTransparentCoroutine()); isLoading = false; } private void updateGameStateAndFireEvents(GameState newState) { GameState oldGameStae = this.gameState; this.gameState = newState; OnGameStateChangedEvent.Invoke(this.gameState, oldGameStae); } private IEnumerator playGameOverAnimationAndSwitchScene() { this.updateGameStateAndFireEvents(GameState.GameOver); yield return new WaitForSeconds(1.5f); AudioManager.Instance.GetAudioSource(AudioClip.Explosion).Play(); Player.Instance.Explosion.Play(); yield return new WaitForSeconds(0.4f); PersistantStorage.Instance.Score = Player.Instance.Score; this.SetGameState(GameState.GameOverMenu); } public void SetGameState(GameState gameState) { if(gameState == GameState.Play) { if(!isLoading) { isLoading = true; StartCoroutine(loadGameSceneCoroutine()); } } if(gameState == GameState.GameOver) { StartCoroutine(playGameOverAnimationAndSwitchScene()); } if(gameState == GameState.GameOverMenu) { SceneManager.LoadScene("GameOverMenu"); this.updateGameStateAndFireEvents(GameState.GameOverMenu); } if(gameState == GameState.Menu) { SceneManager.LoadScene("Menu"); this.updateGameStateAndFireEvents(GameState.Menu); } } }