Setting up the correct listener properties is something interesting to think about depending on the type of game we are working on. In first person games it’s easy: the listener’s panning and attenuation settings correspond to the position of the camera. The player sees and hears the world based on the player’s head and therefore camera position. In this case we can simply use the Studio Listener component provided by the FMOD Integration. But what about other type of games? How should the listener be configured in a third person game in which the camera and player positions are independent from each other? In this short tutorial we will create a script to manually define panning and attenuation attributes for the studio listener.
In non first-person games we have to take into account the location of the player and camera in terms of panning and attenuation. Sound sources will sound different depending on what affects these two elements. Take this 2D platformer situation for example:
If both attenuation and panning is based on player’s head position, the enemy’s sound will be panned to the left, although the enemy is positioned on right part of the screen (camera). In this case, having panning based on position of the camera seems like a more appropriate solution.
Setting up custom panning and attenuation listener attributes for a Third Person Game with FMOD in Unity (< 2.01.00)
Let’s create a new script called CustomListener.cs. We will declare two GameObjects, namely the Camera and the Player at the start of the class.
[SerializeField]
private GameObject player, cam;
[SerializeField]
private int listener;
FMOD.ATTRIBUTES_3D attributes = new FMOD.ATTRIBUTES_3D();
void Update()
{
attributes.position = FMODUnity.RuntimeUtils.ToFMODVector(player.transform.position);
attributes.forward = FMODUnity.RuntimeUtils.ToFMODVector(cam.transform.forward);
attributes.up = FMODUnity.RuntimeUtils.ToFMODVector(cam.transform.up);
FMODUnity.RuntimeManager.StudioSystem.setListenerAttributes(listener, attributes);
}
attributes.position is the position vector being passed to FMOD. attributes.forward and attributes.up are used for the panning information. If your game only has one listener, you can set the listener variable to zero. Save the script, add it to a new or existing GameObject, add the Player GameObject to the Player field and the camera GameObject to the Cam field in the inspector:
Start your scene and listen to the panning taking into account your camera movement.
Setting up custom panning and attenuation listener attributes for a Third Person Game with FMOD in Unity (> 2.01.00)
With FMOD 2.01.00 the setListenerAttributes
method got an optional parameter for the attenuation position. To make use of this new feature we can declare a new FMOD.VECTOR
at the start of the class:
FMOD.VECTOR playerPosition;
Then we convert the transform.position vector of the player to a FMOD.VECTOR
by calling:
playerPosition = FMODUnity.RuntimeUtils.ToFMODVector(player.transform.position);
Finally we pass playerPosition
as a third argument in the setListenerAttributes
method:
FMODUnity.RuntimeManager.StudioSystem.setListenerAttributes(listener, attributes, playerPosition);
The full code looks like this:
[SerializeField]
private GameObject player, cam;
[SerializeField]
private int listener;
FMOD.ATTRIBUTES_3D attributes = new FMOD.ATTRIBUTES_3D();
FMOD.VECTOR playerPosition;
void Update()
{
attributes.forward = FMODUnity.RuntimeUtils.ToFMODVector(cam.transform.forward);
attributes.up = FMODUnity.RuntimeUtils.ToFMODVector(cam.transform.up);
attributes.position = FMODUnity.RuntimeUtils.ToFMODVector(cam.transform.position);
playerPosition = FMODUnity.RuntimeUtils.ToFMODVector(player.transform.position);
FMODUnity.RuntimeManager.StudioSystem.setListenerAttributes(listener, attributes, playerPosition);
}