Now that we have prettied up our game, it is time to give our game a loose condition.
For this purpose, I will be diving a bit into the ‘Singleton pattern’ and creating a new ‘GameManager.’ For the time being, our ‘GameManager’ will be responsible only for knowing when the game is over - for now, that will be when our player dies.
What is Singleton, what are the advantages and disadvantages, and when to use it?
Singleton pattern is used when you wish to create a class with only a single globally accessible instance available at all times. This is very handy when you want to create methods for other classes to access.
However, there is a bit of controversy when talking about this design pattern, and it is not everyone's cup of tea. That is why there are specific situations when it is very beneficial, and you need to know the pros and cons of when to use it. So make sure you do not misuse and abuse the singleton pattern.
- It is straightforward to use and understand - There is only one instance of an object and one way to get that object, and it is globally accessible.
- It can be used to maintain data across different scenes
- Supports Interfaces
- Supports Inheritance
- Relatively good performance
- Good to use when you don’t need extendability
- Tight connections. Modifying the singleton can easily break all other code that depends on it, leading to a lot of refactoring.
- No polymorphism.
- Not very testable.
- Relatively easy to misuse and abuse!
Examples of use:
The recommendation is to use Singletons for things that need to exist only once, and there is no need to copy them multiple times throughout the game.
- Single-player games - The player is a singleton.
- Managers and System Controllers( Audio, Camera, …)
Before diving deep into the Singleton implementation, we first have to adjust our ‘Enemy’ and ‘Player’ scripts to define when our player dies.
First, we open our ‘Player’ script and add two new variables. One will hold the maximum number of lives, which will be set at the start of the game, and the other will hold our current number of lives.
Next, we have to create a new public method, which we will call ‘Damage.’ This method will be ‘public’ so that other scripts can access this method.
As we can see, if our lives will be less than one - we destroy this GameObject, our player. And whenever the player gets damaged, the new ‘Damage()’ method is called, and the player loses a life.
Finally, we have to update our ‘OnTriggerEnter2D’ method in the ‘Enemy’ script
We have to create a new script called ‘GameManager’ and attach it to our ‘GameManager’ GameObject.
This is the simplest declaration to make a class a Singleton. We need to instance a static variable of GameManager. The Static tag means that there is only one version of the variable, and no copies can be made.
Next, we have to create a private bool ‘_isGameOver’ and a public method ‘GameOver(),’ which, when called, will set the value of the ‘_isGameOver’ variable.
Finally, to make things easier for us, we can create a public bool method ‘IsGameOver(),’ which will return the state of the game as a bool.
We need to update our ‘Player’ script to call the public method when the player is damaged and update the ‘SpawnManager’ script to stop spawning new enemies when the game is over.
And that is it! We have now created a GameManager responsible for knowing our game's state.
But that is it for now, thank you for reading and feel free to follow me for more articles — and as always, good luck and see you next time!