GameDev Blog #7: Adding an Esc/Pause Menu

Disclaimer: I am neither a professional game developer nor am I a professional programmer. I doubt I am following best practices. This is just what worked for me at the time. Hopefully it works for you if you’re playing along while reading!

Version of Unity used: 2019.4.13f1 Personal

The previous posts in this series can be found under the CardConquest category on this blog. The github for the project can be found here. The zip archive for this specific post can be found here.

In this post, I want to create a “pause” menu that pops up when the player presses the esc key on their keyboard. This will be the first foray into “UI” in this series. Hopefully this will be simple and easy!

The Canvas and Creating the UI

The first thing to do will be to create the “canvas” that will hold all the User Interface (UI) objects of the Esc menu. To create one, right click in Unity’s hierarchy, go down to UI, then select “Canvas.”

You should now see a “Canvas” and “EventSystem” objects created in your scene hierarchy. Select the Canvas, and then rename it to “EscMenuCanvas” to make it easier to keep track of.

Select the EscMenuCanvas and go to the Inspector window. Under “Canvas,” set the “Render Mode” to “Screen Space – Camera.”

Next, you’ll need to set the “Render Camera” for EscMenuCanvas. This will set what camera the canvas will render on. Click on the little circle/target thing next to Render Camera. Then, in the pop-up window, click on “Scene” and select the “Main Camera” from your scene.

In order for the EscMenuCanvas and all the UI objects that will be added to it to render “on top” of everything, set the sorting layer to “UI-Text” and the order in layer to 2.

Next, you will need to adjust settings in the “Canvas Scaler” section. Click the drop down next to “UI Scale Mode” and select “Scale with Screen Size.”

Set the “Reference Resolution” to 1280 x 720. You can set it to whatever resolution you want, but if you change it to something else, your UI elements will not scale the same way as mine.

Finally, make sure that the “Screen Match Mode” is set to “Match Width or Height”, and set the “Match” scale to 0.5.

Creating a Panel

Now that the EscMenuCanvas has been created and configured, the actual menu can start to be created. First, a “panel” will be created that holds the menu items. Right click on EscMenuCanvas, go to UI, and select “Panel”

You should now see a semi-transparent object in your scene that has taken up the whole camera view. First, rename the panel to EscMenuPanel. Then, you can start adjusting the size of the panel. I wanted the menu to be centered and a bit narrow, so I set the “Left” and “Right” values in the “Rect Transform” of the panel to be “400.”

You should now see that the panel is a narrow band in the center of the scene.

In the panel’s “Image,” leave the “Source Image” as the default “Background.” Click on the “Color” and make it whatever color you like. I made mine black, and I adjusted the alpha to be “200.”

Now you should see a darker, less transparent panel in the scene.

Adding Buttons

The Esc menu will need buttons for the user to click on. For now, I will only add two buttons. “Resume Game” to close the menu and go back into the game, and “Exit Game” to quit out of the game.

To create a button, right click on the EscMenuPanel in the hierarchy, go to UI, then select Button.

Rename the button to “ResumeGameButton.” In ResumeGameButton’s rect transform, I set its Y position to be 50, its width to be 300, and its height to be 75. You can set these values to whatever you think looks best. They just set the size and position of the button.

Next, under the “Image” section of ResumeGameButton, uncheck the box next to “Fill Center.” You should now have a empty button with a white border in your scene.

Adding a Font for the Button

In the hierarchy, if you expand ResumeGameButton, you should see a child “Text” object.

After you select the text object, you can edit the text shown in the button. I typed in “Resume Game”. I also set the color to a bright green, think computer terminal green, that has an RGB value of R:51,G:255,B:0.

The only fonts available, though, were Arial and some “Liberation” fonts that I didn’t like. I went to the Unity Asset store and found a free “pixel” font called Theleah that you can find here. If you have created a Unity account, you can add the Theleah font to your assets. Then, you should have the option to “Open in Unity.”

Back in unity, your “Package Manager” should open. In the package manager, you should see the Thaleah font.

With “Free Pixel Font – Thaleah” selected, click on “Import” in the bottom right of the package manager window.

You should now see an “Import Unity Package” window. Click on import.

You should now see Thaleah_PixelFont added as an asset to the project.

Go back to ResumeGameButton’s “text” object in the Inspector, and set the font to “ThaleahFat.” Note, this font is all uppercase.

I set the “Font Size” to 50, and this is what my button looks like in the scene

To create a new button for “Exit Game,” simply copy and paste “ResumeGameButton” in the hierarchy. Rename the button to “ExitGameButton,” change the “Pos Y” value in ExitGameButton’s rect transform to -50, and then change the text to “Exit Game.” You should now see two buttons.

EscMenuManagerScript

The UI elements for the Esc menu have now been made. The next step will be to create an EscMenuManager object in Unity that will control the UI elements, and detect when the user presses the esc key.

In the hierarchy, right click and create an empty object.

Rename the object to ExcMenuManager, reset its transform position to be 0,0,0.

Next, go to your Scripts directory under assets and create a new script called “EscMenuManager.”

Attach EscMenuManager.cs to the EscMenuManager object in unity by dragging and dropping the script onto the object.

Open the EscMenuManager.cs script in Visual Studio.

At the top of EscMenuManager.cs, create the following variables:

public static EscMenuManager instance;
public bool IsMainMenuOpen = false;
[SerializeField]
private GameObject escMenuPanel;

The “EscMenuManager instance” variable will be where you create an “instance” of the EscMenuManager script so other scripts can access its public variables and functions. The boolean variable “IsMainMenuOpen” will be used to quickly check if the esc menu is open. The final gameobject variable “escMenuPanel” will be used to store the EscMenuCanvas object.

To create the instance, first create a new function called “MakeInstance()”

void MakeInstance()
{
	if (instance == null)
		instance = this;
}

Then, make sure to call MakeInstance() from the Start() function.

void Start()
{
	MakeInstance();
}

Now there will be a public instance of the EscMenuManager script for other objects to access.

Next, go back into Unity and attach the EscMenuCanvas to the EscMenuManager object’s script.

This will allow EscMenuManager to turn the canvas on and off so the user doesn’t always see the esc menu. In fact, when EscMenuManager starts, and when the game starts, you want to make sure the Esc menu isn’t displayed. The following code added to the Start() function of EscMenuManager.cs will make sure that when the game is started, the Esc menu UI is hidden to the user.

if (escMenuPanel.activeInHierarchy)
{
	escMenuPanel.SetActive(false);
}

Detecting Esc Key being Pressed

Similar to how MouseClickManager.cs detects when the user clicks their mouse in the game, EscMenuManager.cs will detect when the user presses the “esc” key in the game. Unity makes it easy to detect when esc is pressed with Input.GetKeyDown(KeyCode.Escape). This will return true when the esc key is pressed down.

When the user presses esc, you will want to make the EscMenuCanvas active in the hierarchy so the user sees it. I also wanted it so if the user presses esc again while the esc menu is open, it will close the menu. The following code will allow you to do that by doing the following when esc is pressed:
1.) Set “IsMainMenuOpen” to its inverse. As in, if IsMainMenuOpen is false, set it to true. If IsMainMenuOpen is true, set it to false
2.) Unhide/Hide EscMenuCanvas with “SetActive” being set to IsMainMenuOpen

if (Input.GetKeyDown(KeyCode.Escape))
{
	Debug.Log("Opening the ESC menu");

	IsMainMenuOpen = !IsMainMenuOpen;
	escMenuPanel.SetActive(IsMainMenuOpen);
}

Adding the Button Functions

The esc menu has two buttons, ResumeGameButton and ExitGameButton. When the buttons are pressed, they can be set to run a function. When ResumeGameButton is pressed, I want the esc menu to disappear. So, crete a function called HideEscMenu that basically does the same thing as when the user presses esc:

public void HideEscMenu()
{
	Debug.Log("hiding the main menu");
	if (IsMainMenuOpen == true)
	{
		IsMainMenuOpen = !IsMainMenuOpen;
		escMenuPanel.SetActive(IsMainMenuOpen);
		Debug.Log("hiding the main menu");
	}
}

Save EscMenuManager.cs and go back into Unity. Select the ResumeGameButton in the hierarchy and then go to the Inspector window.

In the “Button” section, you should see something called “On Click()” at the bottom. Click on the “+” sign

You then have the option to select an object. Click the little circle button, then in the new window go to “Scene”, and then select EscMenuManager.

You should now see a drop down that says “No Function.” Click on that, go to EscMenuManager, then select HighEscMenu ()

When you test it out now, you should be able to hit esc to bring up the esc menu, then click on “Resume Game” to close the menu.

For “Exit Game” you can create a simple function called “ExitGame().” The code is as follows:

public void ExitGame()
{
	Application.Quit();
}

Then, attach ExitGame to the ExitGameButton the same way you attached HideEscMenu() to the ResumeGameButton. Note: when you run the game within unity, the Exit Game button won’t actually do anything. That’s because Application.Quit() doesn’t work when running in the Unity editor. It will, however, work if you build and run the game in a separate application.

Preventing Mouse Clicks on Units While Esc Menu is Open

You may have noticed that you can still click on and move units when the esc menu is open. This is less than ideal, but probably not super important. However, it is also very easy to fix.

Because EscMenuManager creates an instance of itself, and it has the public boolean variable “IsMainMenuOpen”, you can add a check to see if the esc menu is open when detecting mouse clicks. Just add the following to the if statements detecting the left and right mouse clicks in MouseClickManager.cs:

&& EscMenuManager.instance.IsMainMenuOpen == false

Now you have an esc menu. Congrats!

Next Steps

The next thing I will likely add to the game is an opening scene/menu where the user selects to start the game, which then loads the GamePlay scene. Fun!