0 votes

I have a master script for buttons that I attach to every single button I create. In this script I specify that the button nodes are to add a child that plays audio when focused on. I call this audio Move. The idea for this audio is that when you move between buttons, the audio will play, giving audible feedback that the input to move from one button to the other was successful.

The downside to how I designed this is that the audio plays as soon as any buttons are on the screen, i.e. when the Title Screen "New Game/Continue/Options buttons fade in for the first time, or when you pause. In other words, as soon as a button comes on screen and is focused on, it makes this noise, rather than only when the focus is switched from one button to the next.

Is there any way to check if nothing has been focused on before this button had focus on it? Some sort of conditional maybe?

First thing that comes to mind is Timers, but I don't think this would work very well; imagine if you just sit in the pause menu for more time than the Timer specifies, then switch buttons? It should play noise in that instance but would not.

Relevant Button code:

# Extensions
extends Control


#Constants
const Sound = preload("res://Audio/Sound.tscn")
const Move = preload("res://Audio/MenuMove.wav")


# Functions
func _ready():
    connect("focus_entered", self, "_on_focus_entered")


func _on_focus_entered():
    var move = Sound.instance()
    self.add_child(move)
    move.stream = Move
    move.play()
Godot version 3.4.4.stable
in Engine by (37 points)
edited by

1 Answer

+1 vote
Best answer

You could have a boolean in the scenes ready which is set to false and only allow the audio to play if the boolean is true. Once the initial period has passed you could then set that boolean to true so the behaviour you want works as expected.

by (3,324 points)
selected by

This worked! I knew it would be something simple like this.

Here's what I did:

1) Added an onready boolean near the top of my Global script to control if the sound can play or not:

#Extensions
extends Node

#Variables
onready var buttonMoveSound = true

2) Changed my master button code's on focus entered() function (see the rest of this code above) to be on focus exited(), which saved the issue of the noise playing every time a button showed up for the first time, and then added an "if" statement inside to say if the global variable was true, play the noise, else, don't, so that I could turn it on and off in different situations on the fly within my game:

func _on_focus_exited():
    if Global.buttonMoveSound == true:
        var move = Sound.instance()
        self.add_child(move)
        move.stream = Move
        move.play()
    else:
        pass

3) Added a line of code to my pause menu code (just a good example of something in my game with a bunch of buttons that enters and leaves the screen frequently) that says when the state is switched from being in the pause menu to being unpaused, set the global variable to false to shut the audio off (so that it doesn't play the move sound when the focus exits from the button that was just on screen in the pause menu), and then when the tween of the pause menu exiting the screen ends, set the global variable back to true to play the audio next time the game's paused:

enum {
    UNPAUSED,
    PAUSEBAR,
}

func _process(delta):
    match state:
        UNPAUSED:                                                      
            unpaused_state(delta)
        PAUSEBAR:
            pausebar_state(delta)

func unpaused_state(delta):
    get_tree().paused = false

        tweenPauseBarIn.interpolate_property(pauseBar, "rect_position",
            Vector2(-320,0), Vector2(0, 0),
            Tween.TRANS_SINE)
        tweenPauseBarIn.start()

        state = PAUSEBAR

func pausebar_state(delta):
    get_tree().paused = true

    if Input.is_action_just_pressed("pause"):
        tweenPauseBarOut.interpolate_property(pauseBar, "rect_position",
            Vector2(0,0), Vector2(-320, 0),
            Tween.TRANS_SINE)
        tweenPauseBarOut.start()

        Global.buttonMoveSound = false

        state = UNPAUSED

func _on_TweenPauseBarOut_tween_completed(object, key):
    Global.buttonMoveSound = true

4) I will now have to repeat step 3 whenever I create new scenes with buttons, but this is no big deal. Easy to fix each time.

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.