[SOLVED] playing a random sound after the previous one stops?

lucas2606lucas2606 Posts: 2Member
edited January 30 in Audio

hi :) i'm new to Godot. 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 :P
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...

Best Answer

Answers

  • s9menines9menine Posts: 3Member
    edited January 26

    First off - you probably don't want to put that in the _process function. You might want to define your own functions instead.

    Also, a slightly cleaner and less error-prone way of choosing a random one out of a fixed number of choices would be to put them in an array, shuffle() it, and access the first entry.

    onready var players: Array = [$s1, $s2, $s3, $s4] # We use the onready keyword because we're dealing with referencing pre-existing nodes, I think
    
    func _ready():
        randomize()
    
    func _random_player() -> AudioStreamPlayer:
        players.shuffle()
        return players[0]
    

    To play from these four sounds non-stop, you could use a while loop.

    func play_sounds(): 
        var i := 1
        while i == 1:
            var player := _random_player()
            player.play()
            # yield waits for the specified object (player) to emit the specified signal ("finished") before moving on
            yield(player, "finished") 
    

    Call play_sounds() in _ready() for immediate autoplay when the parent node gets loaded. Also you didn't need to use a Control node for audio, that's usually used for GUI stuff, a regular plain Node would suffice.

  • cyberealitycybereality Posts: 927Moderator

    Nice solution. Quick question, though. Why use i == 1? Can't we do this?

    while true:
        # some stuff
    
  • s9menines9menine Posts: 3Member

    @cybereality It works! I just didn't know you could use the word true on its own like that haha, thanks for the tip!
    Another reason to use an i might be to change it later and break the loop, though in that case I should've declared it outside of the function.

  • cyberealitycybereality Posts: 927Moderator

    To break out of a loop, you just call break.

    while true:
        # do stuff
        if stuff_is_done:
            break
    

    Cheers.

  • cyberealitycybereality Posts: 927Moderator

    Ah, just noticed you're a new member. Well, welcome to the forum! =)

  • s9menines9menine Posts: 3Member

    Thank you! :3

  • lucas2606lucas2606 Posts: 2Member
    Accepted Answer

    hey! thanks for your replies! the mail with the notification went directly to the spam folder...
    I received two solutions in the Q&A section. I used the yield option
    here's the link: https://godotengine.org/qa/59518/how-to-play-a-random-sound-after-the-previous-one-stop?show=59518#q59518

  • TwistedTwiglegTwistedTwigleg Posts: 2,616Admin

    @lucas2606 said:
    hey! thanks for your replies! the mail with the notification went directly to the spam folder...
    I received two solutions in the Q&A section. I used the yield option
    here's the link: https://godotengine.org/qa/59518/how-to-play-a-random-sound-after-the-previous-one-stop?show=59518#q59518

    Great! Thanks for linking to the solution.
    Also, I changed this discussion to a question and marked your post as the answer.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file