Make first focused button silent, or check if nothing was focused prior?

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

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()
:bust_in_silhouette: Reply From: Gluon

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.

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
  1. 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
  1. 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
  1. 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.

PIZZA_ALERT | 2022-05-06 06:04