Thursday 18 May 2017

Gitting Gud At Godot - Part 9 - Sound Effects and Music

In this tutorial, we're going to get into sound effects and music. Unfortunately, since Godot doesn't package any sample sound effects with a new project, I'm going to be using a few of my own files. You can download them from Mediafire below, or use your own.

In Godot 2.1, there are two separate ways to play sound effects. One is by using "samples", and one is by using "streams". Samples are designed to be played quickly, a lot of times and often. This might include things like bullet shots, jumping sound effects, footsteps, or anything in between. Streams are the opposite. They are designed to be played less frequently, but for longer. Usually, the StreamPlayer is used for playing music.

Now, let's get started.

First, add a SamplePlayer node to your scene. Be warned, this is not the same as a SamplePlayer2D node. A SamplePlayer2D node will pan your audio based on its position relative to the camera. I don't tend to use this in general, but either way let's stick to the SamplePlayer node.

Under the Inspector tab, go to "Samples" and from the dropdown menu select "New SampleLibrary". After this, press the arrow to the right to open the SampleLibrary menu, similar to the Animation menu.

From here, you will be able to see a single button on the top-left of the menu. Press this button and open "gunshoot.wav". You should be able to see that this sound effect has been added to the SampleLibrary. You can even press the play button to the left of "Preview" to test it out. Wow!

For the record, yes, I made this sound with a mixture of my mouth, white noise and a lot of Audacity editing.

Let's make it so that this will play whenever we enter our Area2D. Go back to the "player" script and add a few lines underneath "_on_collectable_body_enter".

func _on_collectable_body_enter( body ):
        wall_destroyed = true
    if(body == self):
        var mover_resource = load("res://mover.tscn")
        var mover = mover_resource.instance()
        mover.set_pos(Vector2(100, 100))


All we need to add is that last line. Super easy!

As for the StreamPlayer, add a node of type StreamPlayer to the scene. Under the Inspector tab, select "Stream", "Load" and move to our "these poles are safe with me.ogg" file. Tick the box that says "Autoplay" and the box that says "Loop", and you're good to go!

That actually wraps up this tutorial. That was quick. I'll admit, you probably didn't even need a tutorial for that one.

For now, however, we're about to take a step back. Remember back in Part 7 on instancing that I said instancing was easy? I want to retract that statement. Warning: only read the bit below if you're really confident you know what you're doing. Also, correct me if I'm being an idiot.

Instancing is very easy to do if you're starting out, but once you get into the messy realms of scene inheritance and resource sharing- good luck. To put it simply, if you instance two of the same node, they'll usually opt to share the same resources. This means if you change the resource, it'll change all instances of that resource. To avoid this, it seems you will have to call .duplicate() on a known copy of the resource, and then manually set the resource to the duplicated copy in the new instance.

At least, that's the concept behind it. I have no idea if this will hold up when 3.0 comes along. Good luck!

With that, this series is coming to a (temporary) end. I was never and am not a tutorial guy. I'm notoriously bad at explaining things, so trust me if you enjoy this content, you'll love my primary stuff.

Either way, you now know everything you need to make a solid start with Godot, but even if you don't- I'll be back soon with some more tutorials. Expect them next month.

My release schedule will be back to normal hereafter. Stay tuned, and thanks for reading!


  1. "Expect them next month" Suuuuure.

    On a serious note, I found these tutorials on /r/godot and really appreciate them. Just went through all 9 today and I have a much better grasp on Godot and how it works, especially with the node tree structure. Thanks for taking the time to make these!

  2. in 3.1 SamplePlayer is now AudioStreamPlayer and the steps are still pretty close.

  3. Thanks for the tutorial. I hope you do more!

    SamplePlayer has been replaced with AudioStreamPlayer. To access it in code you now need to use get_node("../AudioStreamPlayer").play(0.0). The '0.0' is a floating point number and it defines the time on the audio track to start playing.