Talking about Pause Menu, we will use a simple approach for pausing most behaviours, which is stopping the time. Most of movement scripts are using time functionality, such as Delta Time, to calculate the amount of movement to apply. In this part, we will setting the timeScale as a way to simulate time going faster or slower. This will affect Unity's time system's speed. By setting the timeScale to 0, it will simulate that time has stopped, which will pause animations, stop particles, and reduce Delta Time to 0, making our movements stop. Do these following steps:

  1. Create a script called Pause and add it to a new object in a scene.

  2. Detect when the Esc key is pressed. We can use GetKeyDown(KeyCode key) to detect it and write it in Update. Then, set the Time.timeScale to 0.

    public class Pause : MonoBehaviour
    {
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Escape))
    				{
    						Time.timeScale = 0;
    				}
        }
    }
    

That is a simple but effective way to pause the game. Next, we will the Pause menu visible to unpause the game. let's take a look at these steps:

  1. Add a field of the GameObject type called pauseMenu in the Pause script. The idea is to drag the Pause menu here so that we have a reference to enable and disable it.

    public class Pause : MonoBehaviour
    {
    		public GameObject pauseMenu;
    		
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Escape))
    				{
    						Time.timeScale = 0;
    				}
        }
    }
    
  2. In Awake, add pauseMenu.SetActive(false); to disable the Pause menu at the beginning of the game. Even if we disabled the Pause menu in the editor, we add this just in case we re-enable it by mistake. It must always start disabled.

  3. Using the same function but passing true as the first parameter, enable the Pause menu in the Esc key pressure check:

    public class Pause : MonoBehaviour
    {
    		public GameObject pauseMenu;
    		
    		void Awake()
    		{
    				pauseMenu.SetActive(false);
    		}
    
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Escape))
    				{
    						pauseMenu.SetActive(true);
    						Time.timeScale = 0;
    				}
        }
    }
    

Now, we will make the Pause menu buttons work. Our Pause menu buttons use the same class to implement the OnClick event, which is an event that informs us that a specific button has been pressed.

Let's resume the game when pressing those buttons by doing the following:

  1. Create a field of the Button type in our Pause script called resumeButton, and drag resumeButton to it; this way, our Pause script has a reference to the button.

  2. In Awake, add a listener function called OnResumePressed to the onClick event of resumeButton.

  3. Make the OnResumePressed function set timeScale to 1 and disable the Pause menu, as we did in Awake:

    public class Pause : MonoBehaviour
    {
    		public GameObject pauseMenu;
    		public Button resumeButton;
    		
    		void Awake()
    		{
    				pauseMenu.SetActive(false);
    				resumeButton.onClick.AddListener(OnResumePressed);
    		}
    		
    		void OnResumePressed() 
    		{
    				pauseMenu.SetActive(false);
    				Time.timeScale = 1;
    		}		
    
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Escape))
    				{
    						pauseMenu.SetActive(true);
    						Time.timeScale = 0;
    				}
        }
    }
    

    Because we disabled the cursor at the beginning of the game, then we have to re-enable it while in Pause so that we can click the Resume button and disable it when we resume:

    ...
    void OnResumePressed() 
    		{
    				pauseMenu.SetActive(false);
    				Time.timeScale = 1;
    				Cursor.visible = false;
    				Cursor.lockState = CursorLockMode.Locked;
    		}		
    
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Escape))
    				{
    						Cursor.visible = true;
    						Cursor.lockState = CursorLockMode.None;
    						pauseMenu.SetActive(true);
    						Time.timeScale = 0;
    				}
        }
    
                                       Showing and hiding the cursor while in Pause
    

After we code the Resume button, let's move to the Exit button which is also included in the Pause menu. Firstly, add using UnityEngine.UI. To exit the game, we will call Application.Quit(). But, this function only works when you build the game. So, if you want to print a message to be sure that the button is working properly, you can follow this following code:

using UnityEngine;
using UnityEngine.UI;

public class QuitButton : MonoBehaviour
{
		Button button;

		void Awake()
		{
				button = GetComponent<Button>();
				button.onClick.AddListener(Quit);
		}
		
		void Quit()
		{
				print("Quitting");
				Application.Quit();
		}
}

Add this script directly to the Quit button GameObject itself so that the scripts listens to the onClick event on its Button component. This will execute the Quit function. You can add this behaviour to the Pause script instead, and it will work too. But, remember that if a script can be split into two because it does two unrelated tasks, it is always best to split it so that separate behavior is unrelated. Here, the Pause behavior is not related to the Quit behaviour.