Repetitive sounds are very noticeable to humans. In games, we’re always trying to vary effects, so they don’t sound too similar.
We have two tools for that:
This is such a common pattern in almost every game that we decided to make it into a custom node.
Additionally, this allows us to demonstrate how easy it is to build your own nodes with custom functionality.
In the props/ directory, create a new script. Call it
RandomAudioPlayer2D.
At the top, write:
class_name RandomAudioPlayer2D
extends AudioStreamPlayer2DWe’re going to export two variables.
The first, sounds, will be an array of audio files. We
will pick a random file from it.
Not every RandomAudioPlayer2D needs to have a list of
sounds. Sometimes, one sound is enough, and we just change the
pitch.
So if no sounds are provided in the sounds array, we
want the player to behave normally.
export(Array, AudioStream) var sounds = []The second variable, randomize_pitch, will be a boolean.
If it is True, we will shift the pitch randomly before
playing.
export var randomize_pitch := trueWe only have one function to write. We want to override the default
play() function of the
AudioStreamPlayer2D.
If we look up the definition of this function in the documentation, we get:
We need to implement the exact same function signature. A function signature is the summary of the inputs it takes and what it returns.
In this instance, play() receives a float,
and returns void. We need to write it exactly like that so
we can override it. Otherwise, we will get an error.
func play(from_position = 0.0) -> void:
passThe function we need to write needs to do the following:
stream property.randomize_pitch is true:
pitch_scale property to a random number between
0.9 and 1.6 (we can pick other numbers. You
can test different values and see how that works out).play() so
we can play the sound with those new properties we set.Try to write it! If you’re stuck, the solution is below:
func play(from_position = 0.0) -> void:
if sounds:
stream = sounds[randi() % sounds.size()]
if randomize_pitch:
pitch_scale = rand_range(0.9, 1.6)
.play(from_position)Once this class is created, we can use it anywhere we would use an
AudioStreamPlayer2D.
For example, we will find it in the Create New Node dialog.
We can now add this node to the Robot, the mob, and use it there.
Open the robot scene. There are two AudioStreamPlayer2D
nodes there.
Locate the script you just wrote, and drag it over the first, then the second node
You’ll notice the script gets attached.
You’ll also find the script referenced in the Inspector at the very bottom:
More importantly, the sounds and
randomize_pitch variables will show up in the
Inspector.
Press the first pain_01.wav file once. Then press
Shift, and press the last pain_05.wav.
drag the files over the sounds array of the
DamageAudio node:
That’s how you use this node!
Do the same with the DeathAudio node and the
death_xx.wav files.
While mobs, bullets, spells, and pickups don’t have alternate audio
files, they can still profit from the randomize_pitch
functionality, so make sure to add the script to all the
AudioStreamPlayer2D nodes you encounter.
Note: For inherited scenes like
Mob.tscn, Spell.tscn, and so on, you only need
to attach the script in the base scene. All inherited scenes will be
able to use it too.