This is the testing Godot forums! All forum posts unique to this forum will be deleted! Please use the main forums here for any posts you want to keep. All forum rules still apply.

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

lucas2606lucas2606 Posts: 2Member
edited January 2020 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 2020

    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: 928Moderator

    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: 928Moderator

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

    while true:
        # do stuff
        if stuff_is_done:
            break
    

    Cheers.

  • cyberealitycybereality Posts: 928Moderator

    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,561Admin

    @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

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.