I have set up a standard 3D event in FMOD and used a sample sound to test how to implement a simple 3D effect for my 2D top-down game.
I have only one audio listener attached to my player. The game is like an asteroid game, so the camera position is static and the player is clamped inside the camera viewport.
When an enemy dies, I start the simple 3D event I have configured in FMOD Studio.
Where position, is the last position on enemy death.
So here is my problem. Even if I set it all correctly the sound is odd, like is placed randomly, sometimes I hear it from the left ear from the right one, etc…
I don’t know why it behaves like this, but I think is something related to distance and the 3D parameter that I have passed to the event.
I think I understand what’s the problem. My player rotates, and reading the code of the FMOD Library, it passes position and rotation toward the FMOD Listener attached to the player.
The audio behaves randomly because is listened to using the player’s forward direction, and not only its position. How can I listen to 3D audio without taking in account the listener’s direction/rotation?
For anyone who has the same problem, I used a hacky solution.
The fact that FMOD Listener cannot help you change the attenuation object during runtime, and you have only one audio listener in your game, you have to build a wrapper for the listener to set its position in space depending on your game state.
For example, since my player can be spawned and respawned, the “spawner” takes into account the listener position update while there is a player on board ( Not attaching the listener to the player, since the listener catches even the object direction ).
When in the menu, etc… the listener is set back to (0, 0).
I don’t think that the audio listener should be dumb like this, but since there is no other options.
I think that FMOD can improve in this by:
- Setting listener per spatial audio type or tag? An example can be, using a listener for menu audio and one for gameplay audio. Since the listener can exist in the same scene, they overlap each other right now, but if you manage a way to filter which listener should “listen” it would be an improvement.
- Open up the FMOD Listener to set up the tracked object, or attenuation object.
The FMOD Studio Listener component wraps around most of the FMOD system listener functionality, which depending on your specific need would make it more difficult to create an all-encompassing component to handle this as you’d have to modify the plugin code, or swap to handling it yourself.
That said, I can definitely see the case for expanding the functionality of the Studio Listener component, as a number of things that you’ve noted, such as listener filtering/priority, could be useful to users. I’ve noted your suggestions on our internal feature/improvement tracker.
To address some of what you’ve mentioned:
This is correct. The velocity of the GameObject (if it exists) is also passed to FMOD to calculate doppler.
The simplest way to do this is to manually/override strip the rotation components from the 3D attributes that you pass to the FMOD system with
Studio::System::setListenerAttributes. Currently, setting the attributes is handled in
StudioListener.Update(), where the list of all listeners is iterated over, and each has their 3D attributes passed to the system with
On your first point, FMOD does offer the ability to assign weights to listener to determine how much that listener influences spatialization - [
On your second, if you modify
StudioListener.attenuationObject in StudioListener.cs to be public, you should be able to reassign it from your own code at runtime if needed.