I need some sort of an if statement, which allows me to disable any input and incrementing score while I'm in the pause menu. The problem is that I don't really understand this kind of pausing code, I'm "used to" the regular boolean one. So, I show all the code.
First script:
public enum GameState
{
Gameplay,
Paused
}
Second script:
public class GameStateManager
{
private static GameStateManager _instance;
public static GameStateManager Instance
{
get
{
if (_instance == null)
_instance = new GameStateManager();
return _instance;
}
}
public GameState CurrentGameState { get; private set; }
public delegate void GameStateChangeHandler(GameState newGameState);
public event GameStateChangeHandler OnGameStateChanged;
private GameStateManager()
{
}
public void SetState (GameState newGameState)
{
if (newGameState == CurrentGameState)
return;
CurrentGameState = newGameState;
OnGameStateChanged?.Invoke(newGameState);
}
}
Third script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PauseController : MonoBehaviour
{
public void PauseGame()
{
GameState currentGameState = GameStateManager.Instance.CurrentGameState;
GameState newGameState = currentGameState == GameState.Gameplay
? GameState.Paused
: GameState.Gameplay;
GameStateManager.Instance.SetState(newGameState);
}
}
And as last, here is what I've done in my character movement script:
void Start()
{
GameStateManager.Instance.OnGameStateChanged =
OnGameStateChanged;
}
private void OnDestroy()
{
GameStateManager.Instance.OnGameStateChanged -= OnGameStateChanged;
}
private void OnGameStateChanged (GameState newGameState)
{
enabled = newGameState == GameState.Gameplay;
}
This is all the code. Where and how am I supposed to write the input and score increment "blockings"? I am so sorry for this being so long and I am grateful if you read all this! :)
CodePudding user response:
Approach 1. Where you have your score/input logic, you can check, if the state is Gameplay, and if not - just return. Like this:
if (currentGameState == GameState.Gameplay)
{
CheckInput();
UpdateScore();
}
else
{
return;
}
Another approach (better) is to have score update and input logic incorporated into current GameState. But you should rework your code:
You need the base GameState class:
public abstract class GameStateBase
{
public abstract void UpdateScore();
public abstract Vector2 GetInput();
}
Then you need 2 actual states, inherited from it:
public class GameStateGameplay : GameStateBase
{
public override void UpdateScore()
{
//---- DO SOME SCORE LOGIC HERE
}
public override Vector2 GetInput()
{
// for example, your input is mouse position:
return Input.mousePosition;
}
}
public class GameStatePause : GameStateBase
{
public override void UpdateScore()
{
//---- DO NOTHING HERE, BECAUSE ITS PAUSE
}
public override Vector2 GetInput()
{
//---- RETURN ZERO HERE, BECAUSE ITS PAUSE
return Vector2.zero;
}
}
Then, you need your state manager, simplified:
public class StateMachine
{
public GameStateBase CurrentState;
public void SetGameplay()
{
CurrentState = new GameStateGameplay();
}
public void SetPause()
{
CurrentState = new GameStatePause();
}
}
Finally, where you doing your actual game logic, you can get current state - whatever it is, pause or gameplay - and let it handle your things:
private StateMachine _myStateMachine; // you can get it as a singleton instance, or somewhat else...
private void Update()
{
_myStateMachine.CurrentState.UpdateInput();
// assume, this is some PlayerObject:
transform.position = _myStateMachine.CurrentState.GetInput(); // Gameplay will return you actual input, and your object will move. Pause returns always zero, and object wouldn't move.
}
WHy it's better? Because this way you can implement as many states as you want. You can not create a new state everytime, but create it once, store references, and then just assign one to _current. You can make states as MonoBehaviours, and state machine too. It's highly recommended to learn about state machines, because it's used widely in game development.
CodePudding user response:
After hours of reading about state machines, I don't feel like I got any more into the topic. I understand now why is it optimal and for what its suggested use is. But I totally don't get the use of it in code. Sorry for the slow tempo, but can you show me how exactly do I have to implement this statement:
if (currentGameState == GameState.Gameplay)
{
CheckInput();
UpdateScore();
}
else
{
return;
}
Into my actual (for example) movement code?
void CheckInput()
{
//if first input then ignore
if (firstInput)
{
firstInput = false;
return;
}
//here is where I want to implement, so if the game is paused, ChangeDirection will not play
if (Input.GetMouseButtonDown(0))
{
ChangeDirection();
}
}
Sorry again for having these basic questions, but I am not an expert (I bet you didn't realize it yet :D) and this is also so much different from a simple boolean.