This article will cover using the Godot FMOD plugin to play sound assets that are generated from an FMOD project. If you have not already integrated FMOD with Godot, then check out my tutorial here to get started.
We will be creating a character that walks around with audible footsteps. The sound of the footsteps will vary with each footstep and can be set to different surfaces.
Creating FMOD Banks
We will be using sound banks from the FMOD examples project that is installed with FMOD Studio.
Step 1: If you do not have FMOD Studio installed, then download and install it from the FMOD Downloads page. Ensure that it matches the same version of the FMOD Engine
that you have installed to work with the fmod-gdnative
plugin.
Step 2: Run the FMOD Studio application.
Step 3: Open the FMOD Examples
project. This project comes with FMOD Studio and is located in its installation folder. On Mac OS X the project is located at /Users/<username>/Library/Application Support/FMOD Studio/2.00.15/Examples/Examples.fspro
.
<FMOD Studio installation directory>
└── Examples
└── Examples.fspro
Step 4: Select File
and then Build
from the menu. This will build all of the sound banks in the examples project and export them in a Build
folder alongside the examples project. You should now have the following files in your directory structure.
<FMOD Studio installation directory>
└── Examples
├── Build
| └── Desktop
| ├── Dialogue_CN.bank
| ├── Dialogue_EN.bank
| ├── Dialogue_JP.bank
| ├── Master.bank
| ├── Master.strings.bank
| ├── Music.bank
| ├── SFX.bank
| ├── Vehicles.bank
| └── VO.bank
└── Examples.fspro
We will be using the Master.bank
, Master.strings.bank
, and SFX.bank
files.
Creating the Main Character
Step 1: Create a new Godot project that uses the fmod-gdnative plugin. See my tutorial here if you need help getting started.
Step 2: Create a new Node2D scene by selecting Scene
and then New Scene
from the menu. Choose the 2D Scene
as the root node.
Step 3: Rename the root node to Player
by double clicking on it.
Step 4: Save the scene as Player.tscn
by selecting Scene
and then Save Scene
.
Step 5: Create a child Sprite
node by pressing the plus button under the Scene
tab. Search for Sprite
and click Create
.
Step 6: Create a new texture for the sprite node by clicking on the [empty]
field to the right of the Texture
property in the Inspector
. Click Load
and then select the Godot icon.png
and click Open
.
Step 7: Click the play triangle in the top right hand corner of the editor to run the game. If you are prompted to set a main scene, then accept your player scene as the main scene for now. You should see the Godot icon in the top left of the window.
Adding Movement
Next we will add movement to the main character.
Step 1: Add a new script to the Player
node by first clicking the root Player
node and then clicking the script icon to the right of the Filter nodes
search bar. Leave the defaults and click Create
.
Step 2: The script editor should automatically open. If it does not then switch to it by clicking the Script
tab at the top of the editor and select the Player.gd
file.
Step 3: Paste the following code into the Player.gd
file. This will allow the player to move around the screen based off of the project’s default input actions. If you defined different input actions, then ensure you use them in the is_action_pressed()
functions instead of the project defaults.
const SPEED: int = 200
var _velocity = Vector2.ZERO
func _physics_process(delta):
_get_input()
position = position + _velocity * delta
func _get_input():
_velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
_velocity.x = 1
_velocity.y = 0
if Input.is_action_pressed("ui_left"):
_velocity.x = -1
_velocity.y = 0
if Input.is_action_pressed("ui_down"):
_velocity.x = 0
_velocity.y = 1
if Input.is_action_pressed("ui_up"):
_velocity.x = 0
_velocity.y = -1
_velocity = _velocity.normalized() * SPEED
If you run the game you should now be able to move the Godot icon around the window.
Initializing FMOD
Next we need to initialize FMOD and load the sound banks we are going to use.
Step 1: Create a new folder in your project by right clicking in the FileSystem
panel and selecting New Folder
. Name it banks
.
Step 2: Copy the Master.bank
, Master.strings.bank
, and SFX.bank
files into the newly created banks folder. You should now have the following directory structure in your Godot project.
<Project root, i.e. res://>
├── addons
| └── <fmod-gdnative plugin>
├── banks
| ├── Master.bank
| ├── Master.strings.bank
| └── SFX.bank
├── icon.png
├── Player.gd
├── Player.tscn
└── <other project files>
Step 3: We first need to initialize the FMOD engine before using it. Add the following line into the player’s _ready()
function.
Fmod.init(1024, Fmod.FMOD_STUDIO_INIT_NORMAL, Fmod.FMOD_INIT_NORMAL)
This line initializes the FMOD engine with a max of 1024 channels and passes the default initialization flags to both the FMOD Studio and FMOD Core systems.
Step 4: Load the sound banks that we built with FMOD Studio (still inside of the _ready()
function).
Fmod.load_bank("res://banks/Master.strings.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://banks/Master.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
Fmod.load_bank("res://banks/SFX.bank", Fmod.FMOD_STUDIO_LOAD_BANK_NORMAL)
At this point you can run your game and you should see output that indicates FMOD was successfully initialized and that the sound banks were loaded. If you did not see the expected output, then double check your initialization above and ensure you are loading the Master.strings.bank
file before any other bank file.
Fmod Gdnative interface managed by a GDScript wrapper
FMOD Sound System: Successfully initialized
FMOD Sound System: LOADING BANK ./banks/Master.strings.bank
FMOD Sound System: BANK bank:/Master.strings LOADED
FMOD Sound System: LOADING BANK ./banks/Master.bank
FMOD Sound System: BANK bank:/Master LOADED
FMOD Sound System: bus:/SFX/Character added to buses
FMOD Sound System: bus:/SFX/Ambience added to buses
FMOD Sound System: bus:/SFX/Explosions added to buses
...
Playing a Sound
Now it’s time to make some noise! We can add footsteps for our character by triggering an FMOD event and letting the FMOD engine play the sound for us.
Step 1: We need to create a Timer node that will continuously trigger sound events while moving. Click the Player
node and then the plus sign in the Scene
panel. Search for timer, select the Timer
node, and click Create
.
Step 2: Leave the default properties for the Timer. i.e. Process Mode of Idle, Wait Time of 1, One Shot as Off, and Autostart as Off.
Step 3: Select the Timer
node on the Scene
panel and then select the Node
panel. Select the Signals
tab if it is not already selected.
Step 4: Connect the timeout()
signal of the Timer
node to the Player
node by selecting timeout()
and clicking Connect
. Ensure you are connecting to the Player
node and leave the defaults for the connection. Then click Connect
. This will create a new method in the Player node’s script called _on_Timer_timeout()
.
Step 5: Switch back to the script editor and add the following code inside of the new _on_Timer_timeout()
method.
Fmod.play_one_shot("event:/Character/Player Footsteps", null)
This will tell the FMOD engine to play the Player Footsteps
event from the SFX
bank we built earlier.
Step 6: Now we just need to start and stop our Timer at the appropriate time. Add the following lines inside of the _physics_process()
function. This will simply start our timer if the Player’s velocity is not zero, meaning the player is moving, and stop it otherwise. We also fire off one footstep immediately when starting the timer so we are able to hear the initial footstep.
if _velocity != Vector2.ZERO:
if $Timer.is_stopped():
Fmod.play_one_shot("event:/Character/Player Footsteps", null)
$Timer.start()
else:
$Timer.stop()
Running the game should now allow you to hear footsteps at a one second interval while moving. You can of course play with the Timer Wait Time
parameter to change the frequency of the steps.
Also notice that the footsteps vary with each step even though we call a single FMOD event. This is just one of the many powerful features of FMOD. In this scenario, the event was set up with multiple footstep sounds and FMOD randomly chooses one on each event call.
Adding Different Surfaces
It’s also possible to pass parameters to FMOD events, which can then be used to change the outcome of what the sound will be. We can use this method to adjust the sound of our player’s footsteps all while using the same event!
The Player Footsteps
event can take a surface
parameter that defines what surface is being walked on, either carpet, grass, or a wood floor. The surface parameter is defined in FMOD Studio and can be viewed by selecting the Banks
tab and then the Character/Player Footsteps
event under the SFX
bank. We simply need to provide this surface parameter to the FMOD event with the desired value to change the sound of the footsteps.
Step 1: First let’s define the available surfaces with the other variables at the top of the Player.gd
file.
enum Surfaces {
CARPET,
GRASS,
WOOD,
}
Step 2: Change the two play_one_shot()
calls to the following. This will fire the same player footsteps event, but will specify that it is on a grass surface, which has a value of 1.
Fmod.play_one_shot_with_params("event:/Character/Player Footsteps", null, {"surface": Surfaces.GRASS})
You should now be able to move the player around and hear a different sound for the footstep, this time as if the player were walking on grass! You can change the surface again to Surfaces.WOOD
to hear the player walking on a wooden floor.