Menus don't stay visible

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By druidpeter

I have a menu controller node that is a CanvasLayer node, and I have a canvas layer and multiple menu nodes below the menu controller node.

The following control code handles toggling between the regular game mode and opening the game menu and pause screen:

(:Edit: There is a variable, “isInMenu” that is set to false initially on scene load. Thank you. :3 )

func _process(delta):	
	if Input.is_action_just_pressed("game_menu") and isInMenu == true:
		# Exit game menu.
		for child in children:
			child.visible = false
			child.set_process(false) 
			
		player.set_process(true)
		isInMenu = false
		
	var tmp = ""
	if Input.is_action_just_pressed("pause_game"):
		tmp = "PauseMenu"
	elif Input.is_action_just_pressed("game_menu") and isInMenu == false:
		tmp = "GameMenu"
		isInMenu = true
		
	for child in children:
		if child.get_name() == tmp:
			child.visible = true
			child.set_process(true)
		else:
			child.visible = false
			child.set_process(false)
			
	if tmp == "PauseMenu":
		pause_game()
	elif tmp == "GameMenu":
		player.set_process(false)

My issue is that when pressing the button on the controller for activating the game menu, the menu will simply flicker visible for a single frame and then immediately exit. I’m wondering if there’s something wrong in this code that is causing this.

Or is my code basically correct, and there’s likely something somewhere else going on?

Alternative implementation ideas are also welcome. Thank you for your time! :smiley:

:bust_in_silhouette: Reply From: Inces

what does pause_game() function do ?
Because it is triggered in your code on both pausing and unpausing. I bet You make your menus visible and right after that pause_game is triggered, and hides them back.

It’s just a simple wrapper function to:

func pause_game():
	get_tree().paused = true

This function should only be called when activating the pause menu, though. But maybe the check for that is failing, perhaps? I’ll check and see.

druidpeter | 2022-08-08 17:49

Ah, sorry, I mistook your action inputs, so it is not that.

Now I understand what is going on. It is the way You introduced var “tmp”. When no input is pressed, it is just "". Because of this, get_name()matches tmp only in a frame input is pressed, and fails right afterwards, rendering everything invisible again.

Generally this whole approach is not good way to handle switching game states. It is very code and framework heavy, non reliable. Things like switching are best done by one-time functionality of Godot, like signals, setget or state machines.
However if You wish to keep your approach, the simple fix is to introduce var tmp in high scope ( not in process, but in high p[art of script ), just like isinmenu var

Inces | 2022-08-08 19:15