0 votes

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! :D

Godot version 3.4.2 Stable
in Engine by (20 points)

1 Answer

0 votes

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.

by (7,755 points)

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.

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

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.