How to PAUSE a Game | Unity Tutorial

Поділитися
Вставка
  • Опубліковано 2 жов 2024
  • Time.timeScale was not my cup of tea. Make a custom class to gain full control over how each object will pause. Keep i mind that this is one way of pausing, you can apply the same idea in different ways.
    I did a follow up video talking more about timeScale: • I was wrong about Time...
    ★ Join the Kingdom:
    / discord
    ► The GameDev Website: gamedev.lu
    ········································
    ● X: x.com/GameDevLu
    ● Instagram: / gamedev.lu

КОМЕНТАРІ • 45

  • @this-is-gamedev
    @this-is-gamedev  8 місяців тому +2

    Thanks all for the great comments! This made me reconsider the usage of timeScale. I’ll post an additional explainer video about this subject.

  • @JasonM-qt3jv
    @JasonM-qt3jv 8 місяців тому +8

    You're replying to other comments saying 'what about interactive menus, animators, particles, music, etc, that will stop functioning when timescale is set to 0?' But there is a solution built right into Unity that is for this exact problem, it's called unscaled time. Anything using Time.unscaledDeltaTime will continue to run as though the timescale were set to 1, even when it's set to 0. There are even toggles on the particle system and animator components to use unscaled time to ensure they keep working when the timescale is 0. For audio sources, they already play independently of the timescale, so if they're not working properly when timescale is set to 0, then it means that in whatever code is calling your play/stop/whatever functions you need to be using unscaledDeltaTime instead of normal deltaTime.

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому +5

      That’s true. And for simple use case this is fine. Personally, for larger projects, or when you start including more third-party libraries you will reach the point where you need custom behaviours when the pause event kicks in. Really not a fan of mixing deltaTime along with unscaledDeltaTime.

  • @sealsharp
    @sealsharp 8 місяців тому +14

    Working around the issues of timescale seems simpler than designing around this.

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому +5

      In some simple cases yes. Once you need an interactive menu, inventory UI and handle music changes, timescale becomes a limitation.

    • @sealsharp
      @sealsharp 8 місяців тому

      @@this-is-gamedev and I will go for timescale. If I happen to be wrong with that, I will post that here and you may say "I told ya" ;-)

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому +2

      All good! Whatever works, works. I just present more ways to do something :)

    • @fernandopena6206
      @fernandopena6206 20 днів тому

      for animations and audio to be played while the timescale is set to 0, just set the animator and the ausiosource update mode to unscaled time

    • @TheyBroughtBackStupidHandles
      @TheyBroughtBackStupidHandles 2 дні тому +1

      If you're already using an event system (like you should in MANY games) then all you have to do is make a new class that inherits from monoBehavior, change that 1 thing in your pauseable scripts, change your timescale line to instead freeze that class, and it works. This gives you way more functionality while paused.

  • @trtl_playz
    @trtl_playz 8 місяців тому +4

    Thanks i had no clue wat the time scale code was thanks for puting it at the begining. very easy to use.
    (for anyone wondering)
    Time.timeScale = 0 //pause the game
    Time.timeScale = 1 //unpause or play the game

  • @Johan-rm6ec
    @Johan-rm6ec 2 місяці тому +1

    Finally a decent video about the topic, following Brackeys and the likes tutorials brings you nowhere and keeps you in tutorial hell forever.

  • @Nin10doLetsPlay
    @Nin10doLetsPlay 8 місяців тому +1

    We in Unreal Blueprints only have a Node called "Pause Game". No need to add complicated stuff 😎

  • @goldone01
    @goldone01 4 місяці тому

    Other people have already said this; but I'd strongly advocate that Time.timeScale = 0 is the right way to pausing Unity in most situations.
    This is because it will pause all things related to time, e.g. particle systems, physics as well as your mono behaviour code if it uses Time.deltaTime; and coroutine work as well. For example, in the video, you can see the smoke still flying because the time scale is unchanged; but it would pause if using the time scale method.
    Unity has lots of ways to have things not be impacted by time, e.g. you can change a flag in the particle systems to use unscaled time (same for the animator); and if you want a specific game object not to be paused, just use Time.unscaledDeltaTime instead of Time.deltaTime, and it will still work. Equally, Coroutines have a WaitForSecondsRealtime option if you don't want to have it paused.
    Where pausing via time scale becomes messy is when you also want to have the ability to do slow motion; or have multiple objects that can pause/unpause the game. In that case, having a single TimeManager class that handles time can make this cleaner.

  • @gwynbleinn
    @gwynbleinn 8 місяців тому +6

    Honestly, I can't imagine a situation in which "timescale = 0" is such a bad practice, that we need to do so much work for pausing every coroutine, particle system, animator, etc...
    Unless when some script should stop at one pause, and should not stop at another.
    But again, can't imagine an ordinary game with 2 mechanically different pauses.

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому

      As soon as your pause menu becomes slightly more complex, where other animators, particle effects or other components affected by timescale need to keep running, is the timeScale approach annoying to use.

    • @jacobester3846
      @jacobester3846 8 місяців тому +4

      Pausing rigid body velocity might be a nightmare without timescale

    • @gwynbleinn
      @gwynbleinn 8 місяців тому

      @@this-is-gamedev I understand that this approach is more flexible and controllable. But I have a strong feeling that this is not about “noob and pro” or “good and bad”, but about necessity.
      Like, ok, I need a scenario where during a pause some objects stop, while others, such as particle systems, are slowed down using a timescale. But how often is this really needed? I don't think it's often enough, to do all this extra code in each project

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому +2

      Fair enough! Didn’t mean to degrade other approaches. It is good to have those discussions and code is always refactorable :D . I’ll post an update in the next days covering Time.timeScale in more detail and the differences with enabling/disabling monobehaviours.

    • @dreamteckstudio
      @dreamteckstudio 8 місяців тому

      You can use unscaledDeltaTime for all that.​@@this-is-gamedev

  • @Luai_Salah
    @Luai_Salah 8 місяців тому +2

    I really feel like this is an extremely bad solution... The beauty of setting the time scale to 0 is all game behaviors that are "time driven" will result in 0 which should be handled as paused.
    The other thing is when the game is paused I don't have to be concerned that my none time driven systems will stop because the update and fixed update loops will continue working as intended. And if I happen to need to stop input from the update loop then in that case I will specify add this Mono Behavior to be disabled as part of pausing the game. Instead of having to go through each and every object and mark it as "pausable"... This will just result in a lot of unhandled objects and states which will take more time debugging and fixing to work.
    And when it comes to animations and UI it will be as simple as setting the animator from "Normal" to "Unscaled Time" and in code just switching from "Time.deltaTime" to "Time.unscaledDeltaTime"
    It's much easier to work around limitations of time scale rather than working around the limitations of "not having an game loop while paused"

    • @Luai_Salah
      @Luai_Salah 8 місяців тому

      Though you are not entirely wrong. This could be handled better. Instead of pausing the game from where you need to pause with time scale, try to always have one place that is changing the time scale, your "PauseMenu/PauseManager" and the pausing will only be triggered from there. And also there should be an event for "OnPauseStateChanged(bool/PauseState)" that you will hook the functionality you need for example disable the kono behaviors that you want to stop. And then finally for stuff that cause problems because the time scale is 0 you just replace the "Time.deltaTime" with "Time.unscaledDeltaTime" and switch your animators from "Normal" to"UnscaledTime" that s should minimize the errors caused by this if there is any... But the major thing is just always make sure you're changing the time scale from 1 and only 1 place. So if any issues happen you know from where it caused, of course this is not an absolute rule but it's just something to avoid

    • @jlr3739
      @jlr3739 5 місяців тому

      Yea, I agree, this is an extremely large, disruptive hammer that requires maintenance on every single thing you design for a relatively small nail. Committing to a base class of 'MonoBehaviourPausable' on everything in your world is weird and will become frustratingly restrictive, not to mention you're forcing a lot of garbage collection on what will ultimately become a really massive delegate object by adding and removing delegates all the time. I'm working on a game where different characters can be moving in different time scales due to time warping in the world, and my solution isn't half as complex as OP's is for just pausing. No offence man! I think you went into super-programmer mode and overengineered something for which there are much simpler, more targeted solutions.

  • @barry_wastaken
    @barry_wastaken 8 місяців тому +1

    Naah, I'll stick with timeScale

  • @MajencioyFulgencia
    @MajencioyFulgencia 4 місяці тому

    Interesante

  • @SepiaDragoonGR
    @SepiaDragoonGR 8 місяців тому

    The only problem I have with time.timescale is that when i pause the game my frames rise to infinity

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому +1

      You can limit the framerate with Application.targetFrameRate

  • @359Aides
    @359Aides 8 місяців тому +1

    Your solution only handles pausing MonoBehaviours. What about physics?

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому

      This can be done in PostPause, PostResume. You switch rigidbodies to kinematic or even better you change the Physics.simulationMode to Script and call Physics.Simulate manually.
      I know this is a lot more work, but Pause != Stop. Lots of systems should still run while just the gameplay is paused.

  • @halivudestevez2
    @halivudestevez2 3 місяці тому

    finally! this is for me! thank you for showing the another way!

  • @nevski999G4merYT27
    @nevski999G4merYT27 7 місяців тому

    Hello, Idk if anyone can help me but im making a game and currently my pause menu pauses the game but not the camera and i cant have click in any buttons

    • @this-is-gamedev
      @this-is-gamedev  7 місяців тому

      Difficult to say. But I did another video talking in details about the TimeScale.

  • @nnNothing
    @nnNothing 8 місяців тому

    just crate script
    =========
    void OnEnable()
    {
    Time.timeScale = 0;
    AnotherDisableComp(true);
    }
    void OnDisable()
    {
    Time.timeScale = 1;
    AnotherDisableComp(false);
    }
    ===========
    and attached to UI Pause Menu Panel
    done, you made Pause Function just be enable and disable one object (UI Pause Menu Panel)

    • @this-is-gamedev
      @this-is-gamedev  8 місяців тому

      How about the music? 🎧 i would like it to fade away to another soundtrack during pause ? ^^ timescale stops the music completely

    • @nnNothing
      @nnNothing 8 місяців тому

      @@this-is-gamedev you can also add keyboard event script to that pause menu panel,
      example script
      =======
      [SerializationField] KeyCode key;
      public UnityEvent onPress;
      void Update()
      {
      if (Input.GetKeyDown(key))
      {
      onPress.Invoke();
      }
      }
      =======
      and attached it to Null Object and Your Pause Panel
      in Null Objek, set key to Escepe, and attach event to enable Pause Panel also disable self
      and for Pause Panel, set it same, but reverse
      so Pause Input will not overlaps with other same key Input

    • @nnNothing
      @nnNothing 8 місяців тому +1

      @@this-is-gamedev for make sound fade, you just need add your AudioMixer fade function to AnotherDisableComp ()
      Edit: it's should be the first Reply Comment, but idk why after I refresh, my last comment gone

  • @xwcott
    @xwcott 8 місяців тому +1

    meanwhile unreal engine:
    PlayerController->SetPause(true)
    done

    • @Raccoon5
      @Raccoon5 8 місяців тому

      sure buddy :D

    • @MisterrSky
      @MisterrSky 8 місяців тому

      meanwhile in unreal no round fillable slider by default

    • @Nin10doLetsPlay
      @Nin10doLetsPlay 8 місяців тому

      Lol as a Unreal Developer I can confirm that this is true 🤓

    • @jlr3739
      @jlr3739 5 місяців тому

      In unity it's just timeScale = 0, this guy is just evangelizing a bad design, (sorry, dude!)
      Systems that you need to keep going even when paused can just use unscaledTime.
      In Unreal the equivalent to what he's done would be making every blueprint or C++ class implement an IPausable interfaces and broadcasting messages to them every time a button is pressed rather than just calling PlayerController->SetPause(true)

    • @xwcott
      @xwcott 5 місяців тому

      @@jlr3739 the default pause system in unreal is exactly what is shown in the video, you can choose the things you want to be paused, meanwhile timeScale = 0 is the lazy way which can be bad for some projects