Un-pause with an input event

Godot Version

4

Question

So trying to set up a pause menu to pop up and pause the game when esc is pressed, in my “main” script i have:
func _input(event: InputEvent): if(event.is_action_pressed("pause") && get_node("Pause").visible == false): get_node("Pause").visible = true get_tree().paused = true # print("pressed") (which is a bit sloppy of a way to write /check it I know but i’m trying to get the pause to work before cleaning up the checking system)
and in my pause scene I have:

func _input(event: InputEvent):
	if(event.is_action_just_pressed("pause")):
		hide()
		get_tree().paused = false
		print("Pressed")

Now it pauses normally with escape, and I have a resume button in the pause scene that works fine but when I try to hit esc when paused it stays paused. I’ve looked through the wiki and saw physics functions will not be called but that should work since my pause scene is set to “when paused” mode, right? I’ve looked up so many tutorials I think my eyes will bleed, and all of them suggest a different method or one that does not work for my situation so any advice is greatly appreciated.

Perhaps the following happens: when the menu is open and you press escape, then the menu closes and afterwards the input event ist additionally handled in the main script.
Have you tried to use set_input_as_handled after processing the event?

See

1 Like

This happens because using get_tree().paused = true by default pauses EVERYTHING. For a menu that triggers get_tree().paused = true, you need to set it to Node → Process → When Paused.

I did it as you can see in the attached screenshot.

It currently is set to that, and the “main” (in this case level1) scene is set to 'pausable"

Also figured a screenshot of level1 would be helpful too

This is because get_tree().paused also stops _input. Try adding this line in line 40 of level1.gd (after get_tree().paused = true):

set_process_input(true)

I don’t know if it will work, but it’s worth checking. Let me know if it helped because you’ve just made me aware that I also have this issue (although I handle the menu only with the mouse).

Unfortunately that doesn’t seem to work for me, I even tried adding it into the pause scene as well, along with adding it into a _ready function with similar results.

Hmmm… Actually, that makes sense. We activated pause, so the next command won’t work. Maybe try using a signal? They work during pause, just like the functions they invoke. CanvasLayer has a signal called visibility_changed(). Your Pause Node is actually a CanvasLayer. Try connecting the signal from Pause to Pause and enter set_process_input(true) there.

I may have misinterpreted what you said, but if this is what you meant, it also does not work but I think signals may be our savior here since like you said technically input is disabled even with it being “when paused”.

And does the signal itself work? Enter some print() command there to be sure. I won’t deal with it today; I need to finish something on my end and I’m off. Tomorrow, I’ll try to figure it out. If you manage to solve the problem on your own, please let me know.

1 Like

Okay so I think that helped me actually figure out the issue, because when I made that Signal print a word it would print once when I paused and then I was seeing when I went to Un-pause it was printing twice while staying paused. So I made the _input event in “level1” work only once and I was able to un-pause it just fine. So it appears that when you go to un-pause, it does so and then immediately pauses itself again by processing the input event in both scenes at the same time causing essentially a loop. I’m going to play around with a way to try and fix this and will reply if I get a solution

1 Like

So my initial guess about what went wrong was correct. Please have a look at my previous post for a method of how to solve it.

1 Like

That worked! Apologies, new to this site and your comment got meshed in with the notifications with the other one, however after making the changes it’s working and i’ll paste my code below. For the level1 scene/function:

func _input(event: InputEvent):
	if(event.is_action_pressed("pause")):
		get_node("Pause").visible = true
		get_tree().paused = not get_tree().paused
		get_viewport().set_input_as_handled()

and in the pause scene/function:

func _input(event: InputEvent):
	if(event.is_action_pressed("pause")):
		get_tree().paused = false
		hide()
		get_viewport().set_input_as_handled()
2 Likes

I published a pause/resume game tutorial. You may find it useful.

1 Like