Topic was automatically imported from the old Question2Answer platform.
Asked By
lucas2606
hi. this is my first day with the engine and my coding skills are very poor. i’m trying to play a random sound when the previous one stops, but i can’t make it. i got a “control” node and 4 audiostreamplayer nodes as childs, “s1”, “s2”, “s3” and “s4”. my control node code is this:
extends Control
var a = RandomNumberGenerator.new()
var sound = 0
func _ready():
a.randomize()
var sound = a.randi_range(1,4)
get_node("s"+str(sound)).play()
pass
func _process(delta):
if get_node("s"+str(sound)).is_active == false:
get_node("s"+str(sound)).play()
pass
the first part of the code works… it randomly plays one of the 4 sounds at the beginning of the scene. i don’t now if this is the best way to do it, but it’s the way that i found
the problem is that i can’t make that when that first sound stop, another one start. the conditional “if get_node(“s”+str(sound)).is_active == false:” give me the error “invalid get index ‘is_active’ (on base: null instance)”
probably is a very noob mistake…
I leave you another alternative way: Use a single AudioStreamPlayer and preload the audio files with preload and put them in an array. Then use the Stream property of AudioStreamPlayer to assign each sound to it. AudioStreamPlayer has a signal that runs every time the playback ends. The problem may be, if you have many files, you have to preload each sound (although there are ways to obtain all the files in a folder: https://forum.godotengine.org/5175/how-to-get-all-the-files-inside-a-folder but I see it half complex and unnecessary for this case.).
Oh, if you are new, you may not know the godot signals, in that case, to connect the finished AudioStreamPlayer signal, select it and go to the Node tab in the properties panel, right next to the Inspector panel and you will see the signals below. Select the signal on_AudioStreamPlayer_finished () and press connect below, in the panel that appears select the node where you have the script. The _on_AudioStreamPlayer_finished () function is automatically created in your script.
estebanmolca | 2020-01-25 13:53
thanks! after a while trying to make it work I discovered the signals watching a sample project
your code works, but I used the yield option because I got a lot of audiostreams (I begun with 4 just for testing, but the idea is to have a lot more) each one with internal variables that I need to call
lucas2606 | 2020-01-26 06:02
Yes, it’s very good. What Yield does is pause the function until a condition is met, in this case it uses the same signal to resume. And you can do more things such as a fade in / out or use some random silence between sounds.
estebanmolca | 2020-01-26 10:26
Thnx, this helped me to bring in some variation into my background sounds. Together with a randomized timer, with a few sounds I get a lot of variation and randomness in my scene.
Another way to play a random set of sounds continually, one after another is via yield. You just need to pick a sound, play it, wait for it to finish (via yield) and then do it again. So, using bits of your above code, something like this:
var a = RandomNumberGenerator.new()
func _ready():
a.randomize()
playSound()
func playSound():
var val = a.randi_range(1, 4) # pick a valid random number
var snd = get_node("s"+str(sound)) # select a sound
snd.play() # play the sound
yield(snd, "finished") # wait for the finished signal
playSound() # do it again