I have created an inventory/quest/system menu, that pops up when the user presses the "ui_menu" button that I have mapped to the Enter key, and the Start button on my gamepad. I want this menu to close when the same button is pushed again. The problem is, the menu opens and then closes before I can even see it. My guess is that the input is being processed by the player code, and then also by the menu code.

How can I get the menu to stay open? Is there a different way I should be handling the input for the UI?

Below are the scripts for the player, and the menu, some things removed for brevity.

player.gd: func _physics_process(delta): if Input.is_action_just_pressed("menu_button"): if get_tree().is_paused() == false: ui_menu.show() get_tree().set_pause(true) emit_signal("menu_open")

menu.gd: func _physics_process(delta): if menu_open == true: if Input.is_action_just_pressed("menu_button"): if get_tree().is_paused() == true: get_tree().set_pause(false) self.hide() menu_open = false func _on_player_menu_open(): menu_open = true

Have you used a Popup or WindowDialog? They are closed when hitting Escape. So when using the Escape button to open the menu they are instantly closed again. At least this is a problem I experienced once. To prevent this behaviour you can set the Popup to Exclusive (popup_exclusive = true). It can not be closed by pressing Escape then, but you could do that via script.

@Unnamed said: Have you used a Popup or WindowDialog? They are closed when hitting Escape. So when using the Escape button to open the menu they are instantly closed again. At least this is a problem I experienced once. To prevent this behaviour you can set the Popup to Exclusive (popup_exclusive = true). It can not be closed by pressing Escape then, but you could do that via script.

No, my UI root node is a MarginContainer. But thanks, that's valuable information I shall try to remember!

I see, the problem is if the player code is executed first and then the menu code it closes the menu again. I guess you tried to avoid this problem by using a signal. It should work if you add yield(get_tree(), "idle_frame") to the first line of the _on_player_menu_open() function. So menu_open will be false until the next frame.

@Unnamed said: I see, the problem is if the player code is executed first and then the menu code it closes the menu again. I guess you tried to avoid this problem by using a signal. It should work if you add yield(get_tree(), "idle_frame") to the first line of the _on_player_menu_open() function. So menu_open will be false until the next frame.

Regarding to documentation you have to use yield(get_tree(), "physics_frame") because func _physics_process() is used and not func _process() Also: Isn't there missing any resume() call after that yield function?

@kryzmak said: Also: Isn't there missing any resume() call after that yield function?

The second argument is the name of an event that will trigger it. So it will be resumed on the next frame.

Thank you @Unnamed , yield(get_tree(), "idle_frame") worked as described!

4 years later