2
\$\begingroup\$

I can successfully pause my game with Godot 4.1 with:

func _process(delta):
        
    if Input.is_action_just_pressed("action_quit"):
        print("pause...")
        pause()


func pause():
    Globals.game_paused = !Globals.game_paused
    print("game paused? " + str(Globals.game_paused))
    get_tree().paused = ! get_tree().paused

But that's as good as it gets: Once the "action_quit" key is hit the game is permanently paused from this point on.

I've got a sneaking suspicion that _process is on holiday at this point and get_tree().paused = ! get_tree().paused isn't being processed. I may be wrong.

How do I check for a keyboard call to un-pause the game?

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

The process_mode of the Node controls when their Script get to run.


By default process_mode is set to PROCESS_MODE_INHERIT, which mean they take the value from their parent.

And, also by default, the process_mode of the root of the SceneTree is set to PROCESS_MODE_PAUSABLE, which means that when you set the paused property of the SceneTree to true, the Node will stop executing its Script...

And since everything else has process_mode set to PROCESS_MODE_INHERIT by default, then every Script stops executing too.


To be able to remove the pause you need an Script to run when paused is true...

That means changing the process_mode of the Node that has the Script.

Aside from PROCESS_MODE_INHERIT and PROCESS_MODE_PAUSABLE, your options are:

  • PROCESS_MODE_WHEN_PAUSED which is the opposite of PROCESS_MODE_PAUSABLE. It will make the Script only run when paused is true. Since you want to use the same script to pause and unpause, this won't work for you.

  • PROCESS_MODE_ALWAYS which makes the Script run regardless of paused. This is what you want.

  • There is also PROCESS_MODE_DISABLED that makes the Script never run. This is sometimes useful to temporarily disable entire Script from code.


I want to reiterate that this is about disabling entire Scripts, not just _process (which you can do with set_process) or any other specific methods. So, no, _unhandled_input won't work.

\$\endgroup\$
1
  • \$\begingroup\$ Oh I forget that I've changed the node process mode to always. By bad, answer deleted. \$\endgroup\$
    – Alex CB
    Aug 26 at 17:56
2
\$\begingroup\$

You are correct in that the _process, _physics_process, _input, and _input_event functions will not be called when a Node is paused. However signals continue to work and cause their connected function to run.

As such you can solve this problem by making a popup or panel to handle pausing. Make sure to set its pause mode to WhenPaused - doing so will ensure that it & its children will work when paused. Then you can add code so that the pressing the pause button will enable & show the pause screen:

func _on_pause_button_pressed():
    get_tree().paused = true
    $pause_popup.show()

To unpause and resume the game, do the opposite when the pause screen is closed:

func _on_pause_popup_close_pressed():
    $pause_popup.hide()
    get_tree().paused = false

You can find more information about this in the pausing games and process mode documentation.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .