End Screen¶
While you’re playing the game, there is a good chance you’ll eventually win or lose. That’s why we need an end screen to give indication on whether the player has lost or won. Several things are being displayed on this screen, such as text telling you if you won or lost, your reached score amount & the level you were defeated on (only when lost the game).
Creating the End Screen screen¶
First, we’ll navigate to the HUD Script to create our End Screen overlay in. We will basically create a black screen, which will be placed on top of the game scene view when the player wins/losses.
So, let’s start with creating a new public static and name it EndScreen.
Next, we create a new private static void and name it CreateEndScreen(). In here we create a new GameObject in which we will place the EndScreen component. We also want to make sure our black overlay/image fills the whole screen. In order to do this we use a combination between transform (to adjust position), SetParent(Canvas.transform); (to make it fill the whole screen/canvas) & SetOffsetAllCorners(0f); (to offset the end screen).
public static class HUD
{
public static Canvas Canvas { get; private set; }
public static DoubleGauge HealthBar { get; private set; }
public static TMP_Text TimerText { get; private set; }
public static TMP_Text ScoreText { get; private set; }
public static EndScreen EndScreen { get; private set; }
public static void Initialize()
{
Canvas = Object.FindObjectOfType<Canvas>();
CreateHealthBar();
CreateTimer();
CreateScoreText();
CreateEndScreen();
}
private static void CreateEndScreen()
{
EndScreen = new GameObject("End Screen").AddComponent<EndScreen>();
EndScreen.gameObject.AddComponent<RectTransform>();
EndScreen.transform.SetParent(Canvas.transform);
EndScreen.transform.SetOffsetAllCorners(0f);
EndScreen.gameObject.AddComponent<Image>().color = Color.black;
}
}
Filling End Screen¶
After making our End Screen overlay and making it appear on the screen, we of course want text to be displayed here as well as other statistics which indicate how well you did in your run. First thing to do is make a new script and name it EndScreen.
Before we begin, make sure you are using the correct namespace in order for everything to work properly. So we want to specify we use TMPro for displaying text & UnityEngine.SceneManagement to manage different scenes.
After making sure you’re using the correct namespace we want to begin with creating a new public class EndScreen and give it a monobehaviour (will use basic Unity/c# functions).
In order to display text, we first need to create a new variable: private TMP_Text _text, _retryText;. As you can see I’ve created two variables here (_text & _retryText). One is for displaying “Victory”/”Defeat” and the other is for placing text on the button, which will help the player navigate to the main screen/start a new game.
using TMPro;
using UnityEngine.SceneManagement;
public class EndScreen : MonoBehaviour
{
public new RectTransform transform => base.transform as RectTransform;
private TMP_Text _text, _retryText;
}
Next on the list is displaying the text, adjusting the size, color and placement. We begin with creating a new GameObject to store our text in so we can adjust it. RectTransform textRectTransform = _text.gameObject.GetComponent
Next, we adjust the placement of our text (SetParenting it, anchoring it with pivot and setting it in the middle).
After adjusting our text placement, we now want specify what kind of text we want to be displayed. So we begin with setting the color of the text to white with _text.color = Color.white;. Now we make sure the text is aligned in the middle with _text.alignment = TextAlignmentOptions.Center;. We give the text a size with _text.fontSize = 100f; and make sure enableWordWrapping is equal to false to prevent words from trying to create a new sentence.
void Start ()
{
_text = new GameObject("End text").AddComponent<TextMeshProUGUI>();
RectTransform textRectTransform = _text.gameObject.GetComponent<RectTransform>();
textRectTransform.SetParent(transform);
textRectTransform.pivot = textRectTransform.anchorMin = textRectTransform.anchorMax = Vector2.one * 0.5f;
textRectTransform.anchoredPosition = Vector2.up * 100f;
_text.color = Color.white;
_text.alignment = TextAlignmentOptions.Center;
_text.fontSize = 100f;
_text.enableWordWrapping = false;
Now we want the text to be displayed when our player wins/losses. We create a seperate Public void for this and call it EndGame() and mention a boolean which will be set true when the player is defeated or wins. We mention our Time.timeScale = 0f; to tell the computer we want the game to freeze when this EndScreen is reached. Next, we create an if-statement to check whether the player has lost or won and depending on this, the text will display VICTORY or GAME OVER.
public void EndGame(bool won)
{
// pauses game
Time.timeScale = 0f;
gameObject.SetActive(true);
if (won)
{
_text.text = "VICTORY!";
}
else
{
_text.text = "GAME OVER!";
}
}
Die function in player script¶
To be able to register dying/winning behaviour we want to create a new function within the player script called Die(). In here we set the EndGame to false to disable the EndScreen and this will be true when our player dies. Now we want to make sure our Die() function is mentioned in the health settings for the player. We basically want to say: if our player’s lives is less than 0 or equal, we want to call our Die() function.
private void Die()
{
HUD.EndScreen.EndGame(false);
}
public float Health
{
get => _health;
set
{
_health = Mathf.Min(MaxHealth, value); // Health can't exceed max health
HUD.HealthBar.Value = _health;
if (_health <= 0)
{
Die();
// Lives--;
// _health = MaxHealth;
}
}
}
Creating Retry Button¶
In order to create a button we type Button button = new GameObject("Retry Button").AddComponent<Button>();
to get the components of a button. Next we want to be able to set the position of the button with RectTransform buttonTransform = button.gameObject.AddComponent<RectTransform>();
.
Next we want the button to be displayed on the screen by creating an Image for it with Image buttonImage = button.gameObject.AddComponent<Image>();
.
Now we can adjust the size and placement of our button. Just like we did above with the victory/defeat text. We also want to repeat this with some retry text, to indicate what this button does when clicked.
At the bottom of the code we want to register a click and mention what this click will do and where it will navigate you to. We do this with button.onClick.AddListener(Retry);. And make sure gameObject.SetActive(false); is set to false to disable the End Screen so it won’t be visable when the game is active and will only be called when the player dies or victors.
Button button = new GameObject("Retry Button").AddComponent<Button>();
RectTransform buttonTransform = button.gameObject.AddComponent<RectTransform>();
Image buttonImage = button.gameObject.AddComponent<Image>();
buttonImage.transform.localScale = new Vector2(1.5f,0.5f);
buttonTransform.SetParent(transform);
buttonTransform.pivot = buttonTransform.anchorMin = buttonTransform.anchorMax = Vector2.one * 0.5f;
buttonTransform.anchoredPosition = Vector2.up * -100f;
_retryText = new GameObject("Retry text").AddComponent<TextMeshProUGUI>();
RectTransform retryTextRectTransform = _retryText.gameObject.GetComponent<RectTransform>();
_retryText.text = "Retry";
retryTextRectTransform.SetParent(button.transform);
retryTextRectTransform.pivot = retryTextRectTransform.anchorMin = retryTextRectTransform.anchorMax = Vector2.one * 0.5f;
retryTextRectTransform.anchoredPosition = Vector2.up;
_retryText.color = Color.black;
_retryText.alignment = TextAlignmentOptions.Center;
_retryText.fontSize = 50f;
_retryText.enableWordWrapping = false;
button.onClick.AddListener(Retry);
gameObject.SetActive(false);
}
Retry function¶
Now we to create this Retry function which we called in the onlick code when the button is pressed. We begin with creating a new function public void Retry(). In here we want the SceneManager to load the first scene with .LoadScene(0); to let the player start over again and try to beat their highscore. Last, we want to set the scene active again, since we disabled it when the player reaches the end screen, so we set Time.timeScale = 1f;.