using NaughtyAttributes;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
//Could be a singleton
public class GameFlowManager : MonoBehaviour {
[SerializeField] [Required]
GameTimer gameTimer = null!;
///
/// True if time is frozen (Start, Pause Menu, Dead)
///
/// Could be renamed appropriately
[field: SerializeField]
public bool Paused { get; private set; } = true;
public BaseState CurrentState { get; private set; } = null!;
bool lastStartButton;
bool lastAcceptButton;
#region Unity Messages
void Awake() => CurrentState = new StartFlowState(this);
void Start() => CurrentState.EnterState();
#endregion
void SetPause(bool value) {
Debug.Log($"Setting pause to {value}");
Paused = value;
Time.timeScale = value ? 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)
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();
Debug.Log("Press Start to start...!");
gameFlowManager.SetPause(true);
}
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.SetPause(false);
}
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.SetPause(true);
}
}
class DeadFlowState : GameFlowState {
public DeadFlowState(GameFlowManager gameFlowManager) : base(gameFlowManager) {}
public override void EnterState() {
base.EnterState();
Debug.Log("You died!\nPress Accept to restart!");
gameFlowManager.SetPause(true);
}
public void ReloadGame() {
Debug.Log("Reloading scene...");
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
#endregion
}