I think both current answers are over-complicating the problem. I think a simple solution like this is adequate and much easier to reason about:
public static class Game {
private static GameState currentState;
public static GameState CurrentState
{
get => currentState;
set
{
PreviousState = currentState;
currentState = value;
OnStateChanged?.Invoke(currentState, PreviousState);
}
}
public static GameState PreviousState { get; private set; }
// Should probably use a custom delegate type instead of Action
public static event Action<GameState, GameState>? OnStateChanged;
}
public enum GameState {
Paused,
Playing,
// Etc.
}
This class simply handles the current game state and is responsible of notifying anyone that cares when the game state changes. Usage would look like this:
// How to change state
if (/* pause pressed */) {
Game.CurrentState = GameState.Paused;
}
// Inside Start() of mainpause menu
Game.OnStateChanged += (currentState, previousState) => {
if (currentState == GameState.Paused && previousState == GameState.Playing) {
// Open this menu
} else if (currentState == GameState.Playing && previousState == GameState.Paused) {
// Close this menu
}
};
// Inside Update() on an enemy
if (Game.CurrentState ==!= GameState.PausedPlaying) {
// Don't do enemy logic while pausednot playing
return;
}
// etc.
If you prefer for this to live inside a game object instead of a static class you can do that too. Just make this class inherit MonoBehaviour, name it something more reasonable, remove static from the properties, and attach it to a game object that you don't destroy.