Sure can. We are going to create an automatic audio player. That not only erases itself after the audio has finished, but also stores the current playing audios in a group so that you can free then when necessary.
For this you will be using "groups", and "singletons".
SceneTree - group methods
You can make a scene that consists of only an AudioStreamPlayer and name the node Audio. Attach a script to it and only put in this:
func _on_Audio_finished(): #by the way this is a signal connection
The next step is creating an autoload script, that can be called from anywhere just by using it's prefix. In this autoload script you are going to preload the previously created scene using:
var Audio = preload("res://Audio.tscn")
Keep in mind that the path to the file may be different for your project, so just copy the path from your editor at the FileSystem's dock.
Next create a function "_play(filepath, type)" these are going to receive the arguments filepath, and type. And then:
var audio = Audio.instance()
var file = load(filepath)
Line by line:
- instances the Audio scene we created first
- adds the instance to the tree. (the path and the parent is your option)
- this adds the instance to a group using the passed argument "type", it is important that "type" hold a String type value, e.g: "BGM" or "SFX"
- this loads the file using the passed argument "filepath" into the file variable. It is also important that "filepath" hold a String type value, e.g: "res://Audio/sword-attack.wav"
- We then set the just created variable file as current audiot to be played by the AudioStreamPlayer.
- And finally we play it using play()
Now, remember that the Audio has a script of it own that will queue_free() itself as soon as the audio comes to an end. But if you want to end it before, you can just use:
var currentPlayingAudio = get_tree().get_nodes_in_group("mygroupname")
You wll use any group name you assigned before in the autoload script.
Then you can iterate through currentPlayingAudio and queuefree() all of then, or just select one or other to queuefree().
Well, that is it. Sorry if it is a little complicated. That was just the way I figured out how to do it.