Event Audio for Godot
Event Audio for Godot
Some time ago I wrote a small add-on for Unity called UberAudio. Unfortunate title aside – ride-sharing wasn’t a big thing back then – it was a simple tool designed to make it easier to add audio to games, based on the system we used in both Dungeon Keeper and Fable.
Since moving some of my personal development focus towards Godot I found myself missing it.
So, here is Event Audio github repo for Godot. (Yes, still a shit title. But better than Uber.)
Basic Workflow
It works as follows:
-
Build an Event bank, which maps ‘audio event’ trigger strings to audio assets.
-
Mount the event bank in your scene somehow. There’s a helper node to do this, or you can do it programmatically.
-
In game, trigger audio events wherever you think audio things will happen.
# 2D example EventAudio.play_2d("hit", thing_playing_audio) # 3D example EventAudio.play_3d("hit", thing_playing_audio)
In this example, the
thing_playing_audio
is the node that the audio is associated with. -
In many cases, that’s largely it, which is the intention – most audio should be ‘fire-and-forget’.
- Triggered audio will automatically track the position and lifetime of the node it’s associated with (optionally).
- Triggered audio will automatically clean itself up.
- Triggering audio events that don’t exist is safe.
Additional Details
Trigger Lookups
A key feature of Event Audio is that trigger strings are structured hierarchically with the separator character +. When and event is triggered, Event Audio will look for a match by incrementally dropping sections of the event string until it finds a match, or runs out of sections.
An example to make this clearer, from the example bank shown above:
hit
maps toshot1.wav
hit+large
maps toshot2.wav
In this case:
- Playing the
hit
event will playshot1.wav
- Playing
hit+large
will playshot2.wav
- Playing
hit+small
will playshot1.wav
. This is becausehit+small
doesn’t exist, buthit
does. - Playing
I+do+not+exist
doesn’t play anything because there’s no match forI+do+not+exist
,I+do+not
,I+do
norI
.
The purpose behind this is to allow arbitrary specialisation of audio events, while building up good defaults. For example, you could compose hit events programatically out of hit+<weapon_type>+<entity_name>+<strength>
. This would result in hit events like hit+sword+goblin+hard
, hit+mace+balverine+light
. Initially you might only map hit, and as polish is added more specialised mappings can be added to the bank – without any code changes.
Other features
-
Variants. For each audio event, multiple audio assets can be associated. When the event is triggered, one will be selected at random. Each of these variants can be given a different weight, to make them more or less likely to be played.
-
Pitch randomisation. Optionally set a min and max pitch for each event.
-
Optional source position tracking. If an audio source is supplied with the event, by default the audio will track the position of the source. This isn’t what is always wanted, however, so the event can be flagged as stationary.
-
Optional source lifetime tracking. By default, audio will play until it finishes. If it should terminate when the source is killed, this can also be flagged in the event bank.
-
2D and 3D playback settings. Playback settings like volume, panning strength and attenuation can be set in the event.
-
Bank editor . All these options are kept together in the details panel of the bank event editor:
-
Manual control. When an event is triggered, it returns a handle to the resulting audio player, which can be manipulated programmatically as normal. This can be handy in the case of e.g. looping audio.
Finishing up
Game audio is such a vital part of the experience, but adding it is often fiddly enough that it’s left to the last moment. The easier you can make it, the earlier you add it; I find fire-and-forget audio triggering makes it much easier.
As always, I’ve made this plugin primarily for my own use, but hope someone else finds it useful.
I’m using it in my projects, but it’s fairly new – so if you hit any issues, let me know.
Simon
- ← Previous
Runtime Debug Tools Update - Next →
Moving from Wordpress to Eleventy