AudioStreamPlayer not playing

mjpateymjpatey Posts: 10Member
edited September 2 in Audio

Hi,

Beginner programmer (not counting Commodore BASIC back in the '80s). Learning Godot with my son! I'm making my first game without a tutorial, a simple platformer similar to the '80s game Jumpman.

In the game, I have these gold pieces to pick up... it's an Area2D scene containing a sprite, a collision shape, and an AudioStreamPlayer named "bling" to play the pickup sound. But the sound won't play. Here's the entire script for the gold piece scene:

extends Area2D

onready var bling = get_node("bling")

func _on_Gold_body_entered(body):
     bling.play()
     queue_free()

The player is feeding the Master bus directly for now, so it shouldn't be an audio routing issue, and it plays just fine in the editor when I turn on "playing" in the inspector. In addition, the queue_free method activates just fine, so the function is definitely being triggered.

Any idea why it's not playing?

Thanks in advance for any light you can shed!

-Mark

Best Answer

  • masonkiethmasonkieth Posts: 4
    edited September 2 Accepted Answer

    Actually, I didn't have it setup like yours. I see the issue. Your queue_free() is deleting the object before it can play the sound. I think a yield will do it.

    `extends Area2D

    onready var audio = get_node("AudioStreamPlayer")
    export var finish_line = false
    signal activated(body_name)

    func _on_CheckPoint_body_exited(body):
    audio.play()
    emit_signal("activated", body.name)
    yield(audio, "finished") #add yield co-routine to prevent the area2d from freeing until the audio has finished
    queue_free()

    func _on_AudioStreamPlayer_finished():
    pass # Replace with function body.`

    Here's how I set up my code using to get it to play and queue. Initially I had just audio.play() and I didn't add a queue_free() because this particular code I just happened to have open wouldn't normally delete. Lol my bad. But it works like this.

    https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html?highlight=yield#coroutines-with-yield

Answers

  • masonkiethmasonkieth Posts: 4Member

    What kind of audio node are you using? I adjusted some code in one of my current projects to match yours and It works as expected. I'm using the AudioStreamPlayer as opposed to an AudioStreamPlayer2D though.

  • mjpateymjpatey Posts: 10Member

    Thanks so much for the response. Actually, I just noticed I'm using the regular AudioStreamPlayer, just like in your test (not 2D).

    I'm using Godot 3.2.1 on Mac. Weird that it works for you and not for me...

  • masonkiethmasonkieth Posts: 4Member
    edited September 2 Accepted Answer

    Actually, I didn't have it setup like yours. I see the issue. Your queue_free() is deleting the object before it can play the sound. I think a yield will do it.

    `extends Area2D

    onready var audio = get_node("AudioStreamPlayer")
    export var finish_line = false
    signal activated(body_name)

    func _on_CheckPoint_body_exited(body):
    audio.play()
    emit_signal("activated", body.name)
    yield(audio, "finished") #add yield co-routine to prevent the area2d from freeing until the audio has finished
    queue_free()

    func _on_AudioStreamPlayer_finished():
    pass # Replace with function body.`

    Here's how I set up my code using to get it to play and queue. Initially I had just audio.play() and I didn't add a queue_free() because this particular code I just happened to have open wouldn't normally delete. Lol my bad. But it works like this.

    https://docs.godotengine.org/en/stable/getting_started/scripting/gdscript/gdscript_basics.html?highlight=yield#coroutines-with-yield

  • mjpateymjpatey Posts: 10Member

    That's awesome, thank you! I've shut down for the night, but will try that in the morning. It makes sense that the queue_free would execute immediately after the sound begins playing (rather than after it's finished). Nice catch, and thanks again! Hopefully will be able to mark this as solved in the morning :-)

  • mjpateymjpatey Posts: 10Member

    @masonkeith that was it! So I used your yield (audio, "finished") idea (substituting my audio stream player's node name) and it successfully played the sound, then deleted the scene. But it was odd not having it disappear immediately. You could run past it and hear the sound, but it was still visible until the sound finished. So I ended up with this:

    extends Area2D
    
    onready var bling = get_node("bling")
    
    func _on_Gold_body_entered(body):
        if visible:
            bling.play()
            visible = false
        yield (bling, "finished")
        queue_free()
    

    ...which made it invisible as soon as the sound started playing, then deleted the instance once the sound finished.

    Thanks so much for the "yield" tip. All is well!

    -Mark

Leave a Comment

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