Configuración de el 3D Audio Listener en Unreal Engine y FMOD

If you prefer to read an English version, click on this button =>

Unreal Engine Version: 5.5.4

FMOD Version: 2.03.06

Este blog post muestra cómo configurar el 3D audio listener en Uneal Engine y FMOD. En este post te muestro cómo configurar este listener en un side scroller, primera persona, tercera persona y en una vista top-down.

Aquí la lista de herramientas y términos esenciales usados en este proyecto:


No todo lo que se requiere para esta configuración está expuesto a Blueprint, por esta razón usé una combinación de Blueprint visual scripting y C++ nativo. Adicionalmente, modifiqué un poco la integración FMOD - Unreal integration para poder resolver los ejemplos en tercera persona, top - down and side scroller.

Importante:

Ten en consideración que esta guía no pretende enseñar diseño de sonido creativo. En cambio, se enfoca exclusivamente en aspectos de implementación y programación de game audio.


Descarga el Proyecto Aquí:

IMPORTANTE!

〰️

IMPORTANTE! 〰️

Prerequisitos:

Para que este tutorial tenga sentido necesitas saber cómo integrar el plugin FMOD en Unreal Engine. Adicionalmente, considera leer y consultar mi post anterior sobre UPROPERTY & UFUNCTION:

IMPORTANTE!

〰️

IMPORTANTE! 〰️

 

Descripción General

Este proyecto tiene cuatro niveles (mapas) distintos con su propio Game Mode. Todos heredan de BP_HGameMode y HGameMode en C++. Configuré el 3D listener en estos game modes por simplicidad.

IMPORTANTE:
Es importante mencionar que si estás creando un juego multijugador, el uso del game mode para este propósito puede no ser una buena idéa ya que esta clase sólo existe en el servidor o el anfitrión, mas no en los clientes. Si este es el caso, considera usar el game state o player controller.

Game Modes

 

Mapas

 

El proyecto FMOD tiene tres grupos de eventos de audio con su propio spatializer shared effect. _2DTD es usado en el side - scroller y el mapa top down, _FP es usado en el mapa de primera persona, y _TP es usado en el mapa de tercera persona. Todos estos estan asignados en el banco MASTER por simplicidad.

 

Cómo funciona el 3D audio?

La posición del listener debe ser actualizada en cada tick, lo que permite al motor de audio actualizar su estado y calcular que tan lejos los emisores de audio están de él. También, el listener actualiza su rotación lo que permite al motor calcular la orientación de los emisores en el espacio 3D.

Así es como este sistema funciona en FMOD y Unreal Engine:

Set Listener Attributes / Set Listener Position

La integración FMOD Unreal llama a FMOD::Studio::System::setListenerAttributes() en el FMOD Studio API pasando el índice del listener y los atributos 3D necesarios como su locación y vectores derecho y frontal.

En la línea 1005 es donde el FMOD API setListenerAttributes() es finalmente invocado.

FFMODStudioModule::SetListenerPosition() es invocado en FFMODStudioModule::UpdateWorldListeners(). Aquí es donde la integración encuentra a todos los jugadores locales y obtiene sus posiciones.

Nota que en la línea 923, la función obtiene la posici[on del listener usando el Player Controller en Unreal Engine.

FFMODStudioModule::UpdateWorldListeners() es invocado en FFMODStudioModule::UpdateListeners(). Aquí es donde la integración resuelve si el mundo del viewport es “Play In Editor” o de un build.

Este proceso empieza cuando el FMOD Studio Module es creado y vinculado a la interface Unreal Engine Media Clock Sink. Esto significa que la actualización del motor de audio audio engine’s se maneja de forma interna por el FMOD Studio Module y no hay necesidad de hacer lo mismo fuera de esta clase.

 

Primera Persona

Para la perspectiva de primera persona, la configuración estandard funciona muy bien. Los “oídos” del listaner se encuentran en la cabeza del peronaje jugador y sigue su rotación. La distancia a los emisores es calculada desde la cabeza del personaje también. Esto es lo que queremos y no hace falta hacer nada más.

Attenuation Override

La configuración por default no funciona para el resto de perspectivas. La locación que necesitamos para los cálculos de distancia no es la misma en donde sucede el paneo. Para abordar este problema, es importante separar estas dos partes del 3D listener y colocarlas en la locación correcta.

Desafortunadamente, la integración FMOD - Unreal asume que sólo queremos crear juegos en primera persona así que no tiene esta opción expuesta por defecto.

 

Revisión de Código!

Aquí te muestro cómo modifiqué el código del plugin para abordad las diferentes perspectivas. Añadí este comentario“<ANS - HVALDIVIESO>“ para envolver el código que modifiqué y ayudarte a ver las diferencias.

Primero, Delaré una nueva función virtual que tiene como argumentos la posición del listener y el attenuation override.

Después, moví la mayoría del código dentro de FFMODStudioModule::SetListenerPosition() al nuevo FFMODStudioModule::SetListenerPositionWithOverride(). Aquí me aseguré de que en caso de existir un attenuation override, la función FMOD::Studio::System::setListenerAttributes() correcta sea invocada.

Finalmente, en FFMODStudioModule::UpdateWorldListeners() comprobré si el Player Controller tiene registrado un attenuation override, e invoco a FFMODStudioModule::SetListenerPositionWithOverride() si ese es el caso.

En la clase HGameMode cree una función llamada AHGameMode::SetupAudioListenerCPP() para configurar este sistema. También, cree una función Blueprint en la clase BP_HGameMode que hace lo mismo: SetupAudioListenerBP

Estas funciones son invocadas desde el game mode de cada ejempo en el evento HandleStartingNewPlayer.

Finalmente, en cada personaje jugador, añadí un scene component con el tag “AttenuationOverride“ conectado al socket: “head” del skeletal mesh o al sprite. Así es cómo estas nuevas funciones pueden encontrar la locación de los attenuation overrides.

 
 
 

2D Side Scroller

En un juego 2D game, la cámara usualmente no rota, pero aún así debemos calcular el paneo desde esta locación. La atenuación es calculada desde la locación del personaje jugador.

La esfera blanca es en donde sucede el paneo, la esfera verde está en el personaje jugador y es donde se calcula la distancia.

Top Down View

En un juego de tipo Top Down view, la cámara tiene una rotación limitada, pero es lo suficiente para afectar el paneo. La atenuación es calculada desde la locación del personaje jugador. Esto asume que la cámara siempre sigue al personaje, si no es el caso, puede que tengas que buscar una solución alternativa cómo forzar a esta posición en el suelo en el centro de la pantalla.

Tercera Persona

En una perspectiva de tercera persona, el paneo se calcula desde la cámara y la distancia desde el personaje jugador. Algunos proyectos implementan ligeras variaciones de esta técnica cómo colocar el listener un poco delante de la cámara, pero la idéa principal persiste: separar donde la atenuación es calculada de donde el paneo es calculado.

Extra: Debugging

En la clase HGameMode cree una función llamada AHGameMode::DrawAudioListenerDebugCPP() para obtener la locación actual del listener y el attenuation override, y después dibujarlos en el viewport. Adicionalmente, declaré una variable de consola variable para activatar or desactivar rápidamente estas esferas.

La función está invocada el el evento tick en BP_HGameMode.

 
 

La esfera blanca es el listener (panning) y la esfera verde es el attenuation override (distancia).

Lo siguiente…

En el siguiente post te mostraré cómo configurar el Spatial Audio Listener en Audiokinetic’s Wwise.

 

EL FIN!

〰️〰️〰️

EL FIN! 〰️〰️〰️

Next
Next

Post MIDI On Event en Wwise y Unreal Engine