using NaughtyAttributes; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; //Could be a singleton public class GameFlowManager : MonoBehaviour { [SerializeField] [Required] GameTimer gameTimer = null!; public enum PauseLevel { NotPaused, PreventActions, WorldFreeze, } [field: SerializeField] public PauseLevel pauseLevel { get; private set; } = PauseLevel.PreventActions; public bool CanDoAction => pauseLevel <= PauseLevel.NotPaused; public BaseState CurrentState { get; private set; } = null!; bool lastStartButton; bool lastAcceptButton; [SerializeField] GameObject startPrompt; #region Unity Messages void Awake() { CurrentState = new StartFlowState(this); if (startPrompt != null) { startPrompt.SetActive(true); } } void Start() => CurrentState.EnterState(); #endregion void SetPauseLevel(PauseLevel value) { pauseLevel = value; Time.timeScale = value >= PauseLevel.WorldFreeze ? 0f : 1f; } public void GameOver() => SwitchState(new DeadFlowState(this)); #region Inputs public void OnStart(InputAction.CallbackContext ctx) { if (!ctx.WasPressedThisFrame(ref lastStartButton)) return; if (CurrentState is StartFlowState) { startPrompt.SetActive(false); SwitchState(new GameplayFlowState(this)); } } public void OnAccept(InputAction.CallbackContext ctx) { if (!ctx.WasPressedThisFrame(ref lastAcceptButton)) return; if (CurrentState is DeadFlowState deadState) deadState.ReloadGame(); } #endregion #region States void SwitchState(BaseState newState) { CurrentState.LeaveState(); CurrentState = newState; newState.EnterState(); } abstract class GameFlowState : BaseState { readonly protected GameFlowManager gameFlowManager; protected GameFlowState(GameFlowManager gameFlowManager) { this.gameFlowManager = gameFlowManager; } } class StartFlowState : GameFlowState { public StartFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {} public override void EnterState() { base.EnterState(); gameFlowManager.SetPauseLevel(PauseLevel.PreventActions); } public override void LeaveState() { Debug.Log("Let the games begin!!"); } } class GameplayFlowState : GameFlowState { public GameplayFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {} public override void EnterState() { base.EnterState(); gameFlowManager.gameTimer.StartTimer(); gameFlowManager.SetPauseLevel(PauseLevel.NotPaused); } public override void LeaveState() { base.LeaveState(); gameFlowManager.gameTimer.PauseTimer(); } } class PauseMenuFlowState : GameFlowState { public PauseMenuFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {} public override void EnterState() { base.EnterState(); gameFlowManager.SetPauseLevel(PauseLevel.NotPaused); } } class DeadFlowState : GameFlowState { public DeadFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {} public override void EnterState() { base.EnterState(); Debug.Log("You died!\nPress Accept to restart!"); gameFlowManager.SetPauseLevel(PauseLevel.PreventActions); } public void ReloadGame() { Debug.Log("Reloading scene..."); SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } } #endregion }