How to pause a game in Unity

The right way to pause a game in Unity

In Scripting Basics by John FrenchUpdated 93 Comments

If you’re making a game in Unity then, chances are, you’re going to need a way to pause it.

This might be to stop the game to display a message, to access inventory or other game settings or to simply offer a traditional pause menu to the player.

Whatever it is, the benefits of being able to freeze gameplay temporarily will be obvious to you.

But, what’s the best way to do it?

Luckily, there’s a simple option.

So… what’s the best method for pausing the game in Unity?

The most convenient method for pausing the game in Unity is by setting the game’s time scale to zero (Time.timeScale = 0), which effectively pauses all time based operations including movement, physics and animation. Setting the time scale to one again will return the game to its normal speed.

In most cases just setting the time scale to zero to pause your game will be all you need to do.

However…

While most operations will be paused when using this method, not everything in the game will be affected.

In some cases, this is by design, for example when designing pause menus that still need to move and animate.

Other times, however, it’s possible to accidentally exclude in-game objects from being paused properly.

In this post, I’ll be exploring what is and is not affected by a time scale pause, how to exclude certain objects from being stopped as well as helping you to avoid some common pitfalls when pausing and unpausing your game.

Let’s get started.

What you’ll find in this article:

Pausing in Unity: Overview video

For a general overview of how to pause in Unity, try my video, or continue to the full article below.

How to pause the game in Unity (using time scale)

To pause a game in Unity, simply set the time scale to zero to pause it and back to one (the default) to unpause it again.

In scripting it looks like this:

void PauseGame ()
    {
        Time.timeScale = 0;
    }

void ResumeGame ()
    {
        Time.timeScale = 1;
    }

How does it work?

Setting the time scale affects the time and delta time measuring variables in the Time class.

Put simply, changing the time scale from its default of one will speed up or slow the game down – for example, you can run the game at half speed with a time scale of 0.5, or twice as fast with a timescale of 2). Setting it to zero, pauses the game entirely.

However, not everything is affected.

Understanding what actually happens when the game is paused using this method will help you to avoid unexpected behaviour later on.

What does and doesn’t get paused

Stopping the game using time scale will, effectively, pause every object that is time-based.

This typically accounts for everything that is happening in the game, as movement is usually scaled by delta time, animation, also, is time-based and physics steps will not be called when time scale is zero.

But not everything is stopped, and understanding what’s happening behind the scenes can help to make building a pause system a little bit easier.

Update will continue to be called

It may surprise you to know that Update will continue to be called when the game’s time scale is at zero.

This means that anything inside of an Update loop, including in coroutines, will continue to run regardless of the time scale, which can potentially cause an issue when detecting input (more on that later).

However, anything that relies on time-based measurement will be stopped, such as animations, time-based delays such as Invoke and Wait for Seconds and all movement, so long as it’s being multiplied by Time.deltaTime.

In practice, this means that, in most cases, everything will be stopped when the game is paused and, even though Update is still being called, nothing is actually happening.

FixedUpdate doesn’t get called at all

How to Pause Physics in Unity - visualisation of objects falling in the editor

When Time.timeScale is set to zero, Physics Steps (Fixed Update) will not be called.

When the time scale is set to zero, Fixed Update will not be called at all.

This is useful as it essentially freezes all physics-based movement automatically whenever the game is paused using the time scale method.

Time will be stopped

When the time scale is set to zero, Time.time, which is the time in seconds since the game started, will be stopped.

In most cases, this is a good thing, as any in-game measurement that relies on the Time.time value will also be paused with it.

But what if you still need to measure time when the game is paused?

Luckily there are a couple of options for doing just that.

Time.realtimeSinceStartup and Time.unscaledTime are not affected by time scale and will continue to measure time even when the game is paused.

Delta time based movement will be stopped

When the time scale is set to zero, all movement will be stopped, but only if that movement is being calculated in units per second (using Time.deltaTime).

What does that mean?

In Unity it’s good practice to multiply movement calculations by Time.deltaTime, which is the amount of time since the last frame. Like this:

void Update()
{
  gameObject.transform.Translate(Vector3.down * Time.deltaTime);
}

This converts the rate of movement from units per frame to units per second.

It’s likely that you’re already familiar with this concept, as it’s used frequently when performing all kinds of actions over a period of time. The purpose being to maintain consistent, smooth movement, even when the frame rate changes (which it will).

But there’s another reason to use Time.deltaTime when moving objects.

When pausing the game using the time scale method, instead of the time since the last frame, Time.deltaTime will be zero.

This means that any movement that is being multiplied by Time.deltaTime, will be multiplied by zero. Which means no movement at all.

Usually, this is the desired behaviour when the game is paused.

If, however, you were to move an object using a fixed multiplier, like this:

void Update()
{
  // Don't do this!
  gameObject.transform.Translate(Vector3.down * 0.02f);
}

In this example, the object would continue to move, even when the game is paused.

But what if you actually do want this behaviour?

For example, what if you want to pause the entire game, except for some objects.

What’s the right way to do that?

How to pause everything in the game except for certain objects

When pausing the game, you may want some objects to continue to move without being affected by the change in time scale.

Luckily, it’s possible to prevent objects from being paused by using unscaled time in place of regular time variables.

For example, to use unscaled time:

  • Instead of Time.deltaTime, use Time.unscaledDeltaTime
  • Instead of Time.fixedDeltaTime use Time.fixedUnscaledDeltaTime
  • Instead of Time.time, use Time.unscaledTime

Most variables in the Time class include an unscaled option that, when used, will ignore changes to the time scale.

Which is ideal for excluding certain objects from being paused, or from other time scale changes as well.

How to use a coroutine when the game is paused

Most coroutines will be frozen when the game is paused.

The coroutine itself isn’t actually suspended.

Instead, the timing elements of the coroutine, such as while loops, Time.deltaTime and WaitForSeconds, cannot complete and are preventing the coroutine from finishing.

But what if you want to use a coroutine when the game is paused?

Just like in the previous example, replacing Time.deltaTime with Time.unscaledDeltaTime will allow the coroutine to run on unscaled time.

There’s also a replacement for WaitForSeconds: WaitForSecondsRealtime, which will operate independent of time scale changes, allowing the coroutine to run as normal, even when the game is paused.

How to animate menus and objects when the game is paused

Animated pause message in Unity game

Use unscaled time to animate menus when the game is paused.

When building a pause menu, it’s likely that your menu screen, buttons and controls will all use animation.

There’s just one problem…

Animation is time-based and when pausing the game using the time scale method, any menu animations will be paused too.

Luckily there’s an easy solution, by changing the Update Mode of the Animator component to use Unscaled Time.

Unity Animations using Unscaled Time

Selecting Unscaled Time will prevent animations from being paused. Great for menus!

The unscaled time update mode ignores time scale changes and is ideal for animating pause menus and other GUIs.

How to prevent control input when the game is paused

While movement will be stopped when the game is paused, Update will continue to be called.

This can cause control input conditions (which are often placed inside the Update loop) to still be checked, even when the game is stopped.

In some cases, this isn’t a problem.

Either because the movement can’t occur or, in the case of physics-based movement, won’t be called at all, as Fixed Update is not called when time scale is at zero.

However…

Allowing gameplay input while the game is paused can cause you problems.

For example, in a top-down 2D game, it might be that player controls may still change the character sprite to face a different direction, even though the character isn’t moving.

Actions and other controls may also still fire, but may not work correctly or at all, only to then trigger when the game is unpaused again.

The controls that move the player, may also be required to navigate the pause menu.

In any case, for these reasons and more, it’s good practice to prevent gameplay input while the game is paused.

So what’s the best way to do it?

The simplest method is to first keep track of whether the game is paused or not with a public static boolean variable, like this:

public class PauseControl : MonoBehaviour
{
    public static bool gameIsPaused;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            gameIsPaused = !gameIsPaused;
            PauseGame();
        }
    }

    void PauseGame ()
    {
        if(gameIsPaused)
        {
            Time.timeScale = 0f;
        }
        else 
        {
            Time.timeScale = 1;
        }
    }
}

Making the variable static means that it is not specific to a single instance (the value is always the same, even if there are multiple instances) and that any class can access it.

Next, place all of the game’s input checks inside if conditions, so that they can only occur if the game is not paused, like this:

public class Jump : MonoBehaviour
{
    void Update()
    {
        if (!PauseControl.gameIsPaused)
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                // Make the player jump!
            }
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                // Player can't jump! (The game is paused)
            }
        }
    }
}

Alternatively, you may want to use a more general condition, similar to the above, but that controls all of the gameplay input, turning it on or off. This would allow you to disable input when the game is paused and also for other purposes as well, such as cutscenes.

Adding this simple condition early on in development will make it easier to prevent unexpected behaviour later.

How to pause all audio in Unity

Audio Source in Unity game scene editor

Pausing the Audio Listener is the easiest way to pause all of the audio in a Unity game.

If you’ve tried using time scale to pause the game, you may have noticed that audio continues to play even when the game is paused.

The Audio DSP time value, which is the audio system time value used for Play Scheduled, will also continue despite the game being paused.

So how do you stop all of the game’s audio when the game is paused?

Helpfully there’s a very easy method for doing exactly that.

Pausing the Audio Listener will pause all audio in the game, as well as the audio DSP time value.

Simply set Audio Listener Pause to true when pausing the game, like this:

void PauseGame ()
    {
        Time.timeScale = 0f;
        AudioListener.pause = true;
    }

void ResumeGame ()
    {
        Time.timeScale = 1;
        AudioListener.pause = false;
    }

Audio that is paused using this method will resume from where it left off when the Audio Listener is unpaused again. Likewise, any audio that was scheduled to play using Play Scheduled will play at the correct time after gameplay is resumed.

But what about menu sounds and music?

What if you want to stop some sounds, but keep others playing?

Helpfully, you can instruct Audio Sources to ignore the Audio Listener Pause state, like this:

AudioSource.ignoreListenerPause=true;

This will allow special Audio Sources, such as for your menu and UI sounds to continue to play, even though other sounds have been stopped.

How to pause the game without using time scale

Setting time scale to zero is, in most cases, one of the most effective and convenient methods for pausing the game in Unity.

Despite this, I’ve seen a number of questions from people asking how to pause the game without using the time scale method.

This is, of course, absolutely fine. What works for one project may not be right for another.

There are options available for doing this, with the most straightforward being to simply check the game’s pause state before running any gameplay scripts. This is similar to the method of preventing control input mentioned earlier.

However…

When reading more about why some people would prefer not to use the time scale method, I was surprised to learn that most of the reasons why were related to not being able to animate menus, move objects, play audio or run coroutines.

Which, as you now know, are all possible to do when using the time scale method.

If it’s simply the case that you weren’t aware that the Audio Listener could be paused, or that animation could use unscaled time or that coroutines can actually be used when the game is paused, then the time scale method may still be the best option for you.

So give it a try.

Now I want to hear from you

How are you pausing your game? Are you using the time scale method or something else?

Did it work, and did anything happen that you didn’t expect?

And what do you know now about pausing a game in Unity that others could benefit from?

Whatever it is, leave a comment below and let me know.

Image Attribution

  • Unity Logo © Unity Technologies
John French profile picture

by John French

Game audio professional and a keen amateur developer.

Get Game Development Tips, Straight to Your inbox

Get helpful tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

How this content was created

This article was written using first-hand research and experience, without the use of AI. For more information on how Game Dev Beginner articles are written, see my writing policy.

Comments

  1. Great article!
    Thanks a lot.
    The reason I’m struggling right now with timescale=0 pause is custom shaders. They stop working. Pause menu itself is a bit complex and you can access a lot of “subscenes” form there with 3d objects that have custom shaders… Some UI items also have custom shaders.

    Workaround seems only one – to pass custom time to the shader.

    1. Couldn’t you simply use Time.unscaledDeltaTime in your custom shaders (that need to continue running code during pause)?

      1. Nice to see it all in one place, have been using all of this pretty much prior to reading this article, hadn’t thought to make the pause bool static as I have a game controller class and getter/setter functions for it from other classes (game objects) and already made my user input dependent on the state of this bool.

        Haven’t used ignore listener pause YET, as my end game menu isn’t that advanced at the minute, that’s next in my list!

        Shame the Unity documentation is so poor at the moment!

        Thanks for putting this all in one place, as it took me ages finding it all from online sources before seeing this, it WILL help others!

  2. I am trying to figure out how to hit the menu button during gameplay, have the game pause and the menu (which I have in another Scene) pop up, and when I want to close the menu and resume gameplay, not have the game restart. I currently have it pause the game using the Time.timeScale and then load the menu Scene. What I have a problem with is when clicking to resume the game scene, it starts the game scene over from the beginning.

    1. Author

      Depending on how complex your menu is, you may wish to try using a same-scene prefab instead, which might be easier to manage. This may or may not be the case, I don’t know your project. Expect to see a guide on this in the future.

  3. Thanks a lot! I paused my games using different work arounds and tripped on some problem, and always wondered which was the correct way of doing pause. Now, seeing your article I can be confident on what I am doing.

  4. This was very helpful, thank you. I’ve got my pause features working absolutely great, but I haven’t put in sound yet and I’ve just started doing animations and I was wondering how those were going to work with pause. Your information will let me move forward with total confidence. Thanks, again!

    1. One thing the article lacks is a description of the video player issues when pausing the game. In my experience, it continues to play.

      1. Author

        Interesting, I’ll take a look at that and update the article.

        1. Have you had a chance to look into this? I don’t think I’ll even be using video pausing in my game, so probably not a big deal. I just saw this in the comments and thought I’d follow up on Sergey’s question for others that come here looking.

          Thanks for the article! I had no idea how to do a pause menu until now. This is my first step in learning it, and what a perfect step it is. Feels like going from 0 to 60 in no time at all.

          1. Author

            Hi William, no sorry, I haven’t. I usually keep a list of extra items and questions to update articles in the future but this one seems to have slipped through the cracks. Sorry about that.

  5. Great article, thanks! I have a game where you give a force to a ball by dragging it (just like angry birds). I also have gravity involved in the game. When I pause the game using a button and disabling the main game empty object, I set a function to that button to set the Time.timescale to 0. In the pause menu I have a resume button that does the opposite: disables the pause menu and enables the main game “empty” with all the elements in it and set the time.timescale to 1. However, when the ball is in the air flying in an orb and I pause it and then resume it, the ball seems to fall in a straight line to the bottom and it doesn’t follow the orb anymore. Any ideas how to fix this?

    1. Author

      As I understand it, that shouldn’t happen. When the TimeScale is zero, physics steps aren’t called, including gravity. The only way I can imagine this would happen is if there’s a movement function happening in Update that isn’t scaled by delta time. Maybe try it on another object or in a different Unity version to troubleshoot.

  6. Many thanks for this – super useful. This is one of those bits of functionality that almost everyone needs, but (as far as I’m aware) hasn’t been covered that well – until now. (I tried to implement pausing on an old project several years ago but couldn’t find comprehensive advice, and ended up just plumping for a store asset instead (sadly now obsolete).

    But this seems to cover everything I need, so I’ve now got the function in my game in a few minutes – everything paused, but nice animated pause menus. Result! (From past experience I’d set aside a lot more time to get this working, so this is a massive bonus.)

    Thanks once again. 🙂

  7. Sweet rundown! Saved me a ton of time digging for info.

    To Pause videos you can do this:

    var videoPlayers = (VideoPlayer[])(FindObjectsOfType(typeof(VideoPlayer)));
    for (int i = 0; i < videoPlayers.Length; i++)
    {
    if (videoPlayers[i].isPlaying)
    {
    playingVideos.Add(videoPlayers[i]); // this is a List
    videoPlayers[i].Pause();
    }
    }

    And to Unpause:

    foreach (VideoPlayer v in playingVideos)
    {
    v.Play();
    }
    playingVideos.Clear();

  8. Great article! Learned a lot about how Time works in unity.

    I’m working on a simple game but want to a robust system to pause the game. Just to prototype –
    1. I have created a PausableBehaviour class which inherits from MonoBehaviour.
    2. A GamePauseController uses FindObjectsOfType(); to get list of all the PauseableBehaviours. This controller also exposes Pause() and Play() methods.
    3. When Pause() is called, it disables all the components that implement PauseableMonobehaviour and enables them again when Play() is called.

    This seems to work and gives flexibility in calling additional functionality when Pause and Play is called. For example, each behaviour can perform additional steps like stopping all co-routines or starting them.

    I don’t know how the system will scale with different types of games. So let me know if you foresee any issues that it may run into.

    1. Author

      Thanks for sharing your feedback. You asked if I could think of any issues with your approach: I’m certainly no expert, but my only thought would be to try to avoid manually starting / stopping behaviours unless you need to. For example, Coroutines, while their conditional loops will continue to be called during a timescale pause, nothing will actually change. So long as the conditions that progress the Coroutine are also paused or, in the case of movement, are scaled by delta time, it can’t advance until the game is unpaused. Your specific use case may be very different of course, my thinking is to avoid interrupting a behaviour that then won’t continue after the pause.

      All the best,
      John.

  9. First, thanks for this article. Very useful.

    I’m using the pause menu in a little 2D game I’m working on and so most of the subjects covered don’t apply to this particular game (but are good to know for future projects).

    One minor hiccup I had was that I use Time.TimeScale (TimeScale) to adjust the difficulty in the game. So TimeScale in my game is dependent on a SerializeField float (that’s adjustable in the inspector), and will possibly be adjustable in-game by users (haven’t decided yet). The problem that arose is that when I tried to set TimeScale directly for the pause feature, the change wouldn’t take. I had to make the change to my float field. Just want to mention this in case anyone else has had a similar problem.

    Secondly, I’ve nested my pauseGame code in my GameSession script. It seemed like a good place to have this code and I haven’t encountered any problems by doing this (so far). GameSession is mainly to persist the score from one level to another; it is kind of a Singleton and so there will only ever be one instance. And so I’m not sure my code requires the gameIsPaused bool to be static, but I’ve made it static just to be safe.

    Thanks again for this useful article.

  10. Holy crap in a pickle barrel, I’m so glad I signed up for these articles. I learned more in this one article than the entirety of my game programming ‘class’. Thank you for the great content, I’m looking forward to devouring much much more of it.

  11. Thank you so much …. This is very helpful and it clears most of my doubts on time scale

  12. This was exactly what I needed trying to write a pauseManager. Big thanks from Sweden.

    Signing up for the newsletter.

  13. Great article! Thank you very much!
    But still I have some issues. Is it possible to not pause physics for some objects? I making a VR game, where UI consist of physical interactive objects. So when game pauses, I need to freeze “world” objects interactions (enemies, bonuses, environment etc.), but Pause menu needs to stay interactive and simulated.

    1. Author

      Thanks! to answer your question, off the top of my head, I’m not aware of a way to selectively pause some physics objects but not others so it’s possible you’ll need some kind of workaround for this.

    2. First of all: thanks for the article, too!
      I ran into the same issue, but 2D. I need Physics to work in the GUI but be frozen in the world. In my case I use RigidBodies to drag and drop some icons into sockets.
      So I came up with this workaround, which seems to work so far:
      – set timeScale to 0. Luckily, this is possible.
      – then in one of your UI behaviours advance Physics manually, whenever you need, via Physics2D.Simulate(Time.unscaledDeltaTime). For 2D I have to also set the Physics2D.simulationMode to SimulationMode2D.Script (and reset it when pause is over). In my case, I only update physics when I drag the icon, which is pretty much sufficient. Physics.Simulate() and I guess Physics.autoSimulation would be the 3D equivalents.
      – set for all active rigid bodies in the world the simulated flag to false (for 3D use isKinematic, I guess)
      – sub hint 1: maybe store inbetween those rigid bodies, which you have changed to ease re-activation when resuming and to not accidentely activate those who were not active before pausing.
      – sub hint 2: omit of course those rigid bodies you don’t want to pause (ui elements), which is easy if your root objects are layers and there is for example a layer named “GUI” that can be omitted easily when traversing root objects of a scene.

      Hope that helps someone.

  14. a great resource, thank you very much, thanks to you I will be able to play the menu effects in the game regardless of time.

  15. Hello, Mr.French

    Thanks for the content. It is really helpful.
    It seems to me, this approach covered the two timelines case. One coincides with reality and the other is controlled by Time.timeScale. For any specific time, every entity belongs to one of the two groups.
    My question is, what if there are more groups. Or more advanced, every entity runs in an individual timeScale. Is there any simple approach, or I have to create a variable called timeScale, and make an implementation for every effected Component.
    Slowing or accelerating globally while ignoring certain entities is quite enough for me. Moreover, user probably won’t even notice slight difference for different entities.
    I’m just curious.
    Greetings,

    Chengqi Li

    1. Author

      Thanks, the general idea behind this is that everything is somehow connected to Time.timescale. i.e. if you’re moving an object you would generally smooth it with delta time, Physics steps aren’t called when timescale is zero and, although Update does get called, you would usually make checks in Update for things that can’t happen while timescale is zero. It’s not a perfect method, but it’s a good starting place, after which you can work through any issues that re specific to your project. HOpe that helps. If not, feel free to email me with any specific questions.

  16. Thanks for the post! One minor thing.
    WaitForSecondsRealTime should instead be WaitForSecondsRealtime

  17. For the scenario when input is carried to the game in play mode when un-paused, I am facing the issue of trigger still carrying forward to the play state. In my Pause menu, the buttons are triggered using ‘A’ or ‘Jump’ button for my game. For eg., When I press ‘A’ on ‘Save’ button in the pause menu, I disable Pause menu and open Game saved message panel which has a OK button, Then again as I press ‘A’ , I disable the message panel. But as soon as the message panel disables the player in my game jumps due to the ‘A’ input getting carried forward. The pause state is tracked in the gameManager script. Sharing the partial code…

    ***Player.cs ***
    ….
    if (gameManager.GetGamePausedStatus() == false)
    {

    if (Input.GetButtonDown(“Jump”) && IsGrounded())
    {
    playerBody.velocity = new Vector2(0, jumpSpeed);
    }

    }

    *** PauseMenu.cs ***
    ….
    public void messageOK() {
    messagePanel.SetActive(false);
    gameManager.SetGamePausedStatus(false);

    Time.timeScale = 1;

    }

    1. Author

      So while I don’t know your project, I’d probably check first if the pause check is definitely working as expected, just to rule out any mistakes. My other thought would be the order of execution possibly calling Update on the Player after the Pause menu (i.e. the game is being unpaused and recognising the button press all within one frame. You could probably test this by moving the Pause Menu function to Late Update, to make sure it happens last. If that fixes it, you’ll know what the problem was.

      1. Thanks for the suggestion John!

        Though I figured the problem was that as soon as the game was un-paused , gameManager.GetGamePausedStatus() became false and in the Player Update function the Inputs start getting registered in the same frame. So to solve this, I created one more bool variable for pause status in the Player.cs file and and changed it at the end of Update function based on gameManager pause status. So that playerPause retains its value when Inputs are checked.

        ***Player.cs ***
        ….
        void Update()
        {
        ….
        if (playerPaused == false)
        {

        if (Input.GetButtonDown(“Jump”) && IsGrounded())
        {
        playerBody.velocity = new Vector2(0, jumpSpeed);
        }

        }
        …..
        …..
        if (gameManager.GetGamePausedStatus() == false) {
        playerPaused = false;
        }
        else if (gameManager.GetGamePausedStatus() ==true) {
        playerPaused = true;
        }
        }

  18. Thanks for the post…pro
    Do you have an educational YouTube channel for the Unity program?
    To subscribe to it… ?

  19. First of all I want to tell you how amazing this article is. Tank you!

    I am making a project in wich the objects can only be moved by the user in pause and my code works perfectly the first time arround but whe I try to move the same object again it stays static.

    do you have any idea why is this happening?

    the pause is implemented with timeScale = 0.

    public class MoveOnDrag : MonoBehaviour
    {
    public Transform Target;
    private Camera cam;
    private float Camera2Distance;

    void Start()
    {
    cam = Camera.main;
    }

    private void OnMouseDrag()
    {
    if (TimeManager.Instance.isPaused)
    {
    StartCoroutine(Positioning());
    }

    }

    private IEnumerator Positioning()
    {
    Camera2Distance = cam.WorldToScreenPoint(transform.position).z;
    Vector3 MouseScreenPosition = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera2Distance);
    Vector3 MouseWorldPosition = cam.ScreenToWorldPoint(MouseScreenPosition);

    Vector3 movement = Vector3.Lerp(Target.position, MouseWorldPosition, Time.fixedDeltaTime * 5f);

    Target.position = new Vector3(movement.x, movement.y, Target.position.z);

    yield return new WaitForSecondsRealtime(0.1f);
    }

    }

    1. Author

      I’m not sure why it’s working once and then not, my guess would be an issue with the wait for seconds at the end but, at a glance, it looks correct. However, you might want to try replacing fixedDeltaTime with unscaledDeltaTime. While there is a fixedUnscaledDeltaTime, I can’t see a reason you’d be using fixed time for this as there are no physics being used and coroutines typically run at the same pace as Update, not Fixed Update. Hope that helps.

      1. I think that the problem is somehow the update of the Transform.position. On the inspector it shows the correct new position but I added a lable to the body that appears when the mouse hover over it and after I move the GameObject it keeps apearing on the initial position… I´ll try to pause the game with a variable instead of the scaleTime so I don´t have this problem anymore.

        Thanks for your reply!

  20. Hi! Good article!

    I use a different method because I don’t like to change the timeScale at any level (it just goes with my way of thinking, I guess).

    What I do is to create an empty interface (IPausable) and when I want to pause the game, I traverse all the components in the scene and check if they are IPausable. If they are, I disable them:

    AudioListener.pause = true;

    var all = FindObjectsOfType( );

    foreach( var c in all ) {
    var p = c as Pausable;
    var a = c as Animator;

    var rb = c.GetComponent( );
    if( rb != null )
    rb.simulated = false;

    if( p != null || a != null ) {
    if( c.enabled ) {
    _enabledStatesBeforePause.Add( c );
    c.enabled = false;

    }
    }
    }

    I disable all the Animators too, and I tend to pause all particle systems, like this:

    var pss = FindObjectsOfType( );

    foreach( var ps in pss )
    ps.Pause( );

    This way, no matter what, the component that I want to be paused will be paused without side effects.

    As you can see, I store the paused componentes in _enabledStatesBeforePause List, just to be able to resume them when pause finishes:

    AudioListener.pause = false;

    var all = FindObjectsOfType( );

    foreach( var c in all ) {
    var rb = c.GetComponent( );
    if( rb != null )
    rb.simulated = true;
    }

    foreach( var b in _enabledStatesBeforePause ) {
    if( b != null )
    b.enabled = true;
    }

    _enabledStatesBeforePause.Clear( );

    And if I want to resume particle systems:

    var pss = FindObjectsOfType( );

    foreach( var ps in pss )
    ps.Play( );

    I hope this approach helps! I really found it very easy to work with, and no intrusive at all for the components. In other words, the components you code doesn’t have to be aware of pausing more than inheriting from IPausable.

  21. Hi! I’ve made some animation for my pause menù screens with lean tween. however, when I pause the game the animations don’t work anymore. I’ve put Unscaled time as the Update mode, but it doesn’t work.

    Here’s the script:

    public static bool gameIsPaused;
    public GameObject PauseMenuUI;

    void Update()
    {
    if (Input.GetKeyDown(KeyCode.Escape))
    {
    gameIsPaused = !gameIsPaused;
    PauseGame();
    }
    }

    void PauseGame()
    {
    if (gameIsPaused)
    {
    PauseMenuUI.SetActive(true);
    Time.timeScale = 0f;
    }
    else
    {
    PauseMenuUI.SetActive(false);
    Time.timeScale = 1f;
    }
    }

  22. Thanks a lot! Really helpful! Simple and great way to use pause functions.

  23. i create a button in the PAUSE Menu ( to take me to the Main Menu )
    but when i go back to main menu with that button , and start the level scene again , i found the level scene still paused and i have to click the key “P” again to start
    how can i make the PAUSING stop when i change scenes
    hope you understand 😀

    1. Author

      I believe that Time.timeScale doesn’t reset when the Scene is reloaded, so you’ll need to set it to 1 again when the new Scene loads. Unless you’re using Don’t destroy on load, you might be able to use Start for this, or Scene Loaded

      1. true , that’s make sense
        i used Time.timeScale method
        how can i make the Time.timeScale rest when new scene loads
        I couldn’t write it correctly ;D

        1. Author

          I’ll test it out and update the article with an example when I can, since others might run into the same issue.

  24. could this be used as a freeze time mechanic in a vr game on oculus? if so (no pressure) could you explain where in unity i would be puting this code?

    1. Author

      Yes you should be able to do that, since that’s essentially what TimeScale = 0 does anyway. You could place it in any script, since Time is a static float and can be accessed from anywhere. Just remember to use Unscaled time for anything that you still want to move during the freeze.

  25. I liked your article. I was using the following code following a tutorial by Jimmy Vargas.

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class PauseGame : MonoBehaviour
    {
    public bool gamePaused = false;
    public AudioSource levelMusic;
    public GameObject pauseMenu;

    void Update()
    {
    if (Input.GetButtonDown(“Cancel”))
    {
    if(gamePaused == false)
    {
    Time.timeScale = 0;
    gamePaused = true;
    Cursor.visible = true;
    levelMusic.Pause();
    pauseMenu.SetActive(true);
    }
    else
    {
    pauseMenu.SetActive(false);
    levelMusic.UnPause();
    Cursor.visible = false;
    gamePaused = false;
    Time.timeScale = 1;
    }
    }
    }
    }

    All of his other codes and steps worked but this one so far. Game is not pausing and the music continues to play. Not sure of the fix.

  26. Can anybody please tell how to make a score history of a player with their names are also mention And how we will give 2 or 3 chance to a player ?

  27. Great advice, but also not perfect. I used timescale to stop everything including particles, but that also disables physics which my UI system, the ever-popular NGUI, uses for UI interactions. Setting timescale to 0 disables the interface and can’t be used. NGUI’s creator’s advice is don’t use timescale to pause.

    As I manage my object objects via scripting, not Monobehaviours, I can handle their updates just fine with timescale > 0, but the problem then is particles continue to play.

    The perfect pause solution, one people should be made aware of earlier in development, is to handle updates yourself rather than Unity’s systems. You can manually call physics updates in a coroutine so you can pause physics without needing to touch timescale. You can log particle effects and pause them each directly. It’s more complex but the only way to be sure you control which parts of the game run and which don’t.

    1. Author

      Thanks for sharing your experience David.

      Personally, I think that, for most people, not using NGUI is the simpler choice here, especially given that there are some reports of incompatibility with newer versions of Unity. However, I can definitely see the benefit of controlling update calls yourself and I’m sure there will be others that need to control their game in the same way. Thanks for your advice.

  28. Thank you so much for this, it’s the perfect lecture for any noob trying to make a clean pause system.

    I always wondered why my inputs were triggered with timescale = 0, and it was so logic that SOME of them NEED to be updated !

    Recommanding your article on our (french ^^) school discord, thank you John French !

  29. Hi,

    Thanks for all your tips.
    I would apply the pause to my game in VR when removing the hmd (quest 2), is someone has a solution?

    Merci encore !

Leave a Comment