I am wondering what’s the most efficient way to apply sounds to UI elements like buttons for hover/select and click/press events?
I’d like to keep it flexible and easily maintainable.
Since I don’t want to go through every button to update their sounds if I ever want to change them, I had an autoloading AudioManager that would be called to
play sounds. Though, I still had to attach a script to every button that would hook up their signals to play said sounds.
You can try using an Autoload and connecting to the SceneTree.node_added signal to connect to the different signals you want to play sounds.
This is an self-contained example:
extends Node
var playback:AudioStreamPlaybackPolyphonic
func _enter_tree() -> void:
# Create an audio player
var player = AudioStreamPlayer.new()
add_child(player)
# Create a polyphonic stream so we can play sounds directly from it
var stream = AudioStreamPolyphonic.new()
stream.polyphony = 32
player.stream = stream
player.play()
# Get the polyphonic playback stream to play sounds
playback = player.get_stream_playback()
get_tree().node_added.connect(_on_node_added)
func _on_node_added(node:Node) -> void:
if node is Button:
# If the added node is a button we connect to its mouse_entered and pressed signals
# and play a sound
node.mouse_entered.connect(_play_hover)
node.pressed.connect(_play_pressed)
func _play_hover() -> void:
playback.play_stream(preload('res://beep_short.wav'), 0, 0, randf_range(0.9, 1.1))
func _play_pressed() -> void:
playback.play_stream(preload('res://beep_long.wav'), 0, 0, randf_range(0.9, 1.1))
Feel free to create a scene with more advanced settings (exporting the audio sounds, creating different audio players,…)
You could use groups to differentiate buttons and play different sounds.