This article explains how to switch between and play multiple sound resources (music and sound effect files) with a single “AudioStreamPlayer” node.

Basically, only one sound resource can be set per “AudioStreamPlayer” node. In other words, you must add “AudioStreamPlayer” nodes in the scene tree for each sound resource. You may feel useless in a situation where there are multiple nodes in the scene tree with the same settings except for the sound resource (as shown in the screenshot below), and you may also feel a little uncomfortable with the lack of visibility in the scene dock.
project settings - window size

So, if you have multiple sound resources that are never played simultaneously (e.g., multiple sound effects for different types of character attacks, multiple sound effects for different types of buttons on the UI, etc.), add only the minimum necessary “AudioStreamPlayer” node for each use to your scene. If you code a program that switches sound resources according to the situation, there will be no waste and the scene dock will look cleaner.

In this tutorial, we will prepare only one “AudioStreamPlayer” node and control the sound resources to be applied to it so that they can be switched and played from a script.

Environment
Godot version: 3.5.1
Computer OS: macOS 12.6

Basic Articles
You may also find the following articles useful.
Downloading Godot
Project Manager of Godot3



Preparation

Project Settings

After starting a new project, go to the “Project” menu > “Project Settings” and make the following settings.

  • In the “General” tab > “Display” on the sidebar > “Window” > “Size” section, set the window size as follows
    project settings - window size

Import Sound Resources

Six .wav files (sound effects) are available in the following Dropbox shared folder.

Dropbox - 共有フォルダ

Drag and drop the entire downloaded “audio” folder into the file system dock to add it to the project.
sound resources - add to the file system


Create a scene

Create the following scene tree. This time, the tree is the simplest ever.

  • UI (Control)
    • SoundLabel (Label)
    • AudioStreamPlayer

Scene tree

When the scene tree creation is complete, save the file as “UI.tscn”.



Edit the nodes

UI (Control) root node

Expand the root node “Anchor” so that it is the same size as the screen. The reason for this is that we want to center the child node “SoundLabel” on the screen after this.

  • Select “Layout” > “Full Rect” from the 2D workspace toolbar. The “Anchor” property will now be automatically adjusted and the 2D workspace will look like this
    UI node - Layout - Full Rect

SoundLabel (Label) node

This node is used to display the path of the sound resource currently applied to the “Stream” property of the “AudioStreamPlayer” node. This allows you to see at a glance which resource file is currently being set and played when you run the project to check its operation.

  • In the inspector, temporarily put “no sound” in the “Text” property.
    SoundLabel node - Text
  • Change the “Align” property to “Center”. This will center the “Text” string horizontally.
    SoundLabel node - Align
  • Change the “Grow Direction” > “Horizontal” property of the “Control” class to “Both”. Now, even if the number of characters in “Text” increases, it will always be displayed in the center of the screen because it will be enlarged in both left and right directions.
    SoundLabel node - Grow Direction - Horizontal
  • Select “Layout” > “Center” from the 2D workspace toolbar.
    SoundLabel node - Layout - Center

AudioStreamPlayer node

This node is used to set a sound resource and play it back. Although the node is originally designed to allow only one sound resource to be set, for this tutorial, we will use this single node to switch between multiple sound resources. The control of this will be done later in a script, but for now, let’s set up the node.

  • Drag and drop “res://auido/coin.wav” from the sound resource file imported from the file system dock to the “Stream” property of the inspector and apply it. This will be the default sound resource for now.


Attach a script to the root node

Now it is time to create a script to control the configuration and playback of sound resources. First, attach a new script to the root node “UI”. The file name of the script should be “UI.gd”. After attaching the script and opening the script editor, edit the code as follows:

###UI.gd###
extends Control

# Array of preloaded sound resources
const sounds = [
    # default resource as 1st element
	preload("res://auido/coin.wav"),
	preload("res://auido/heal.wav"),
	preload("res://auido/hurt.wav"),
	preload("res://auido/shoot1.wav"),
	preload("res://auido/shoot2.wav"),
	preload("res://auido/shoot3.wav"),
]

# Index (from 0 to 5) to specify the resource to be set to
# AudioStreamPlayer among the elements of the array sounds
var index: int = 0

# Reference to SoundLabel node
onready var sound_label = $SoundLabel
# Reference to AudioStreamPlayer node
onready var player = $AudioStreamPlayer


# Built-in function to run when node is loaded
func _ready():
    # Call a method to play sound (defined later)
	play_sound().


# Built-in process function (called every frame)
func _process(_delta):
    # If the right arrow key is pressed
	if Input.is_action_just_pressed("ui_right"):
        # If current index is less than last index of array sounds(5)
        # Add 1 to the current index if it is less than
		if index < sounds.size() - 1:
			index += 1
        # If current index is less than last index(5) in array sounds,
        # set index back to 0
		else:
			index = 0
        # Call a method to play a sound (defined later)
		play_sound()
    
    # If the left arrow key is pressed
	if Input.is_action_just_pressed("ui_left"):
        # If current index is greater than 0
        # Subtract 1 from current index
		if index > 0:
			index -= 1
        # If current index is 0 set the index to the same (5)
        #  as the last index in the array sounds
		else:
			index = sounds.size() - 1
        # Call a method to play sounds (defined later)
		play_sound()
    
    # If spacebar or enter key is pressed
	if Input.is_action_just_pressed("ui_accept"):
        # Call a method to play sound (to be defined later)
		play_sound()


# Method to play sound
func play_sound():
    # Get the element corresponding to the current index from the array sounds
    # Apply it to the Stream property of AudioStreamPlayer
	player.stream = sounds[index].
    # Set the resource path of AudioStreamPlayer's Stream property
    # to SoundLabel's Text property.
	sound_label.text = player.stream.resource_path
    # Play the sound resource of AudioStreamPlayer's Stream property
	player.play()

This completes the editing of the script.

Note that this time I used preload so that sound resources are also loaded when the node is loaded. This may be a good way to avoid delay if the game has a lot of processing. On the other hand, if the game does not require much processing, you can use load to load the resource files just before playback.



Running check

Finally, run the project or scene to check the operation.

As implemented so far, the following keyboard operations can be used to switch sound resources and play them back.

  • Right arrow key: Switch to the next sound resource on the sounds array in the “UI.gd” script and play it.
  • Left arrow key: Switch to the previous sound resource on the sounds array in the “UI.gd” script.
  • Spacebar / Enter key: Play the currently set sound resource


Conclusion

This tutorial has shown you how to switch between multiple sound resources for playback in a single “AudioStreamPlayer” node. Let’s summarize the important points.

  • A single “AudioStreamPlayer” node can switch between multiple sound resources.
  • The above method is implemented to avoid the waste of adding multiple “AudioStreamPlayer” nodes with almost identical settings and to improve the visibility of the scene tree.
  • Sound switching and playback is controlled by scripts.

Of course, if programming is not your forte, adding as many “AudioStreamPlayer” nodes as the number of sound resources to the scene is perfectly acceptable. What we have introduced here is just one methodology, so please feel free to do as you wish, especially in the case of indie development.



References