0 votes

I'm setting up my pause menu and have 3 buttons: Inventory, Party, and Settings. These buttons are textures showing pixel art, which are set to highlight yellow when focused or hovered (all other textures left empty, including the normal, as that is in the Pausebar TextureRect. I would like the first button, Inventory, to be focused as soon as the pause menu launches. No matter where I put inventoryButton.get_focus(), it doesn't do it. In fact, no buttons seem to be able to focus. I would also like to have a Label (shown below as "Pause") to read out the names of the buttons as they are focused, but that's not working either.

Structure and scene look like this, where the buttons are the 3 trapezoids on the left (Pausebar is the node/scene in question here and what is pictured in the editor, but WorldUI is where it needs to work, editable children for PauseBar only for picture, normally turned off):
https://imgur.com/gallery/arVmB8D

Code looks like this (attached to WorldUI scene):

# Extensions
extends CanvasLayer


# Variables
onready var healthUI = $HealthUI
onready var pauseBar = $Pausebar
onready var tweenIn = $TweenIn
onready var tweenOut = $TweenOut
onready var inventoryButton = $Pausebar/PausebarSprite/InventoryButton
onready var partyButton = $Pausebar/PausebarSprite/PartyButton
onready var settingsButton = $Pausebar/PausebarSprite/SettingsButton
onready var pauseLabel = $Pausebar/PausebarSprite/PauseLabel


# Functions
func _ready():
    healthUI.visible = true
    pauseBar.visible = false


func _process(delta):
    if get_tree().paused == true:
        inventoryButton.grab_focus()
        tweenIn.interpolate_property(pauseBar, "rect_position",
            pauseBar.get_position(), Vector2(0, 0),
            Tween.TRANS_SINE)
        tweenIn.start()
    else:
        tweenOut.interpolate_property(pauseBar, "rect_position",
            pauseBar.get_position(), Vector2(-320, 0),
            Tween.TRANS_SINE)
        tweenOut.start()

    if inventoryButton.grab_focus():
        pauseLabel.set_text("Inventory")
    if partyButton.grab_focus():
        pauseLabel.set_text("Party")
    if settingsButton.grab_focus():
        settingsButton.set_text("Settings")


func _on_TweenIn_tween_started(object, key):
    pauseBar.visible = true
    healthUI.visible = false


func _on_TweenOut_tween_completed(object, key):
    pauseBar.visible = false
    healthUI.visible = true

Everything else seems to work fine like the tweens, the visibilities, the functions in general...but for the life of me I cannot get the buttons to obtain focus and use the keyboard to cycle thru them. Using my mouse, I can hover over the buttons and the highlight and clicking side of things works fine (clicking doesn't show a different texture but leaves the button as yellow and shows up in Debugger>Misc). If I load the Pausebar scene on its own and click one of the buttons with my mouse, I can then scroll thru the buttons as intended with the ui_left, right, up, down buttons (yes I have set up the focus neighbors), but this does not work in any other scene, including WorldUI or a standard World level.

I have other buttons in my Title Screen scene, for instance, that work with getfocus() no problem just simply sitting in a Tween-connected function. For WorldUI, I have tried placing the getfocus() line in ready(), process() before and inside the if statement, and where it is now in the Tween-connected function.

Pls halp

Godot version 3.4.4.stable
in Engine by (37 points)
edited by

Okay so I've now spent about a day on this and have gotten a little closer but still this freaking thing is killing me lol.

This is my new structure (editable children for PauseBar only for picture, normally turned off):
https://imgur.com/gallery/aeSzPcK

I've gotten this whole thing to work inside the PauseBar scene by adding a script to PauseBar. The Inventory button starts out as the focused button and I'm able to cycle thru the buttons with the ui_left and right buttons as well as will a mouse cursor (hovering and selection). The label reads what button is highlighted currently as well now, as it should.

Here is that script:

# Extensions
extends Control


# Variables
onready var inventoryButton = $Buttons/InventoryButton
onready var partyButton = $Buttons/PartyButton
onready var settingsButton = $Buttons/SettingsButton
onready var pauseLabel = $PauseLabel


# Functions
func _ready():
    inventoryButton.grab_focus()


func _process(delta):
    if get_focus_owner() == inventoryButton or inventoryButton.is_hovered():
        pauseLabel.set_text("Inventory")
    elif get_focus_owner() == partyButton or partyButton.is_hovered():
        pauseLabel.set_text("Party")
    elif get_focus_owner() == settingsButton or settingsButton.is_hovered():
        pauseLabel.set_text("Settings")
    else:
        pauseLabel.set_text("Pause")

Once the PauseBar is opened in any other scene, however, such as WorldUI for instance, the Inventory button is correctly selected and the Label is correctly read but I am unable to cycle thru the other buttons or change the selection at all via the keyboard or the mouse cursor (hovering does work but selection doesn't work). Here is the WorldUI code as it currently stands now:

# Extensions
extends CanvasLayer


# Variables
onready var healthUI = $HealthUI
onready var pauseBar = $Pausebar
onready var tweenIn = $TweenIn
onready var tweenOut = $TweenOut
onready var inventoryButton = $Pausebar/Buttons/InventoryButton
onready var partyButton = $Pausebar/Buttons/PartyButton
onready var settingsButton = $Pausebar/Buttons/SettingsButton
onready var pauseLabel = $Pausebar/PauseLabel


# Functions
func _ready():
    healthUI.visible = true
    pauseBar.visible = false


func _process(delta):
    if get_tree().paused == true:
        inventoryButton.grab_focus()
        tweenIn.interpolate_property(pauseBar, "rect_position",
            pauseBar.get_position(), Vector2(0, 0),
            Tween.TRANS_SINE)
        tweenIn.start()
    else:
        tweenOut.interpolate_property(pauseBar, "rect_position",
            pauseBar.get_position(), Vector2(-320, 0),
            Tween.TRANS_SINE)
        tweenOut.start()


func _on_TweenIn_tween_started(object, key):
    pauseBar.visible = true
    healthUI.visible = false


func _on_TweenOut_tween_completed(object, key):
    pauseBar.visible = false
    healthUI.visible = true

If I don't have the inventoryButton.grab focus() line in the process function here, nothing get focused at the start, even though I have it working in the PauseBar scene by itself. If I change this line to partyButton or settingsButton it successfully changes the starting button and Label text but I still can't cycle thru or change selection at all (again, hovering does work but selection doesn't work).

Why does this work in its own scene now but doesn't work in any other scene?

And before anyone says it, I know it's not because the WorldUI main node is a CanvasLayer node because I tried it as a Control node as well and there was no change. This needs to be a CanvasLayer node so that it follows the camera around in-world as UI is supposed to.

Please log in or register to answer this question.

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.