Eventos Wwise en Unreal Engine 5 (Post Event) - Game Audio Basics

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

Unreal Engine Version: 5.0.3

Wwise Version: 2021.1.10.7883

Este blog post es un guía sobre cómo disparar “post” un Evento Wwise en Unreal Engine 5 usando Blueprints y código C++. Vamos a crear un evento simple de tipo One-shot y otro evento musical de tipo looping/bucle. Adicionalmente, te mostraré un diseño algorítmico simple para manejar el comportamiento de estos eventos.

Para nuestras pruebas, vamos a disparar nuestras acciones presionando las teclas ER, y T en nuestro teclado. Finalmente, te mostraré como asignar estas teclas a nuestras funciones en blueprints y C++.

Vamos a crear todos nuestros ejemplos blueprints en la clase BP_ThirdPersonCharacter y definir los de tipo C++ en la el archivo MyUE5ProjectCharacter.cpp. Para este tutorial, vamos a aprender como implementar estos eventos usando ambos C++ y Blueprints, entonces asegúrate de abrir ambas clases.

IMPORTANTE!

〰️

IMPORTANTE! 〰️

Prerequisitos:

  1. Crea un proyecto C++ third-person vacio y llámalo “MyUE5Project”.

  2. Descarga e integra el plugin Wwise en tu proyecto por medio del Wwise Launcher.

  3. Activa la opción de Event-Based Packaging.

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

IMPORTANTE!

〰️

IMPORTANTE! 〰️

 

Configuración en Wwise:

Evento One-Shot:

Abre tu proyecto de Wwise. Asegúrate estar en el Designer Layout yendo a Layouts > Designer o presionando la tecla F5 en tu teclado. Da click derecho en Default Work Unit debajo de Actor-Mixer Hierarchy y crea un Sound SFX. Arrastra tu archivo de audio encima de tu effecto de sonido. Puedes nombrar tu sonido como gustes. De manera opcional, puedes asigarle un color para ayudar con la organización.

 
 

Da click derecho a tu nuevo efecto de sonido y selecciona New Event > Play. Nombra tu evento “Play_OneShot”

 
 

Evento Music Loop:

Cambia al Interactive Music Layout yendo a Layouts > Interactive Music o presionando la tecla F10 en tu teclado. Da click derecho en Default Work Unit debajo de Interactive Music Hierarchy y crea un Music Playlist Container. Después, da click derecho en la playlist y crea un Music Segment. Arrastra tu archivo de música sobre tu segmento musical. Drag and drop your music audio file on top of your music segment. Puedes nombrar tu playlist como gustes. De manera opcional, puedes asigarle un color para ayudar con la organización.

La Music Hierarchy debería verse así:

Da click en el Music Playlist Container y arrastra tu Music Segment dentro del Music Playlist Editor. Define la cuenta del loop/blucle como Infinite para que el segmento de música se repita indefinidamente. No olvides definir el tempo!

 
 

Da click derecho en tu nueva playlist y selecciona New Event > Play. Nombra a tu evento “Play_MusicLoop”

Si prefieres, puedes descargar y usar estos sonidos a continuación.

Guarda tu proyecto Wwise. Ve a tu proyecto Unreal y ve a Build > Generate Sound Data > Build. Deberías poder ver y probar tus eventos en el Content Drawer dentro de MyUEProject/Content/WwiseAudio/Events/Default Work Unit.

 
 
 

Configuración C++:

Para simplificar nuestras pruebas, vamos a implementar nuestros eventos dentro del Player Pawn principal. Puedes encontrar la clase C++ padre en MyUE5Project/MyUE5ProjectCharacter y la clase Blueprint heredada/hijo en MyUE5Project/Content/ThirdPerson/Blueprints/BP_ThirdPersonCharacter.

Añade esta directiva de acceso al API Wwise:

.h file:

#include "AkGameplayStatics.h"

Declara un evento Wwise, un entero, y una propiedad booleana.

.h file:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Audio")
UAkAudioEvent* myEvent;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Audio")
int32 myEventInstanceID;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Audio")
bool bIsPaused;

Declara tres funciones, PlayEvent(), PauseEvent(), and StopEvent():

.h file:

UFUNCTION(BlueprintCallable, Category="Audio")
void PlayEvent();

UFUNCTION(BlueprintCallable, Category="Audio")
void PauseEvent();

UFUNCTION(BlueprintCallable, Category="Audio")
void StopEvent();

.h file:

 
 

Guarda tu código y compila en el editor.

 
 

Deberías poder ver estas propiedades en el graph blueprint de tu clase BP_ThirdPersonCharacter:

 
 
 
 
 

Sonidos One-Shot:

Este tipo de evntos no requieren mucho control. Estos tienden a ser cortos en longitud, y muchos pueden existir de forma simultanea. En la mayoría de casos, el dispararlos es suficiente para lograr el comportamiento deseado. En Wwise, podemos limitar cuantas instancias pueden existir simultaneamente.

IMPORTANTE:

Asigna el evento Play_OneShot" a la propiedad My Event.

 
 

Blueprint:

 

Right Click on the graph and search for: “Keyboard Event E“, “Post Event”, “Get My Event”, and “Get a Reference to Self".

 

.cpp file:

void AMyUE5ProjectCharacter::PlayEvent()
{
    UAkGameplayStatics::PostEvent(myEvent, this, 0, FOnAkPostEventCallback());
}

Parametros/Argumentos:

  • AKEvent (UAkAudioEvent*) = myEvent

    El evento Wwise a reproducir

  • Actor (AActor*) = this

    El actor en el mundo al que se le va a vincular el evento. Use this por defecto.

  • CallbackMask (int32 or enum AKCallbackType) = 0

    Este argumento define el tipo de callback en caso que este evento dispare una función callback. Usa 0 para None.

  • PostEventCallback (FOnAkPostEventCallback) = FOnAkPostEventCallback()

    Si este evento dispara una función callback, este argumento va a producir el delegado que va a disparar dicha función. Usa el constructor de la clase FOnAkPostEventCallback() para None.

.cpp file:

 
 
 
 

Sonidos de tipo Loop/Bucle:

En la mayoría de casos, para sonidos de tipo loop, no queremos multiples instancias reproduciéndose simultaneamente. La música y ambientes son claros ejemplos de este tipo de sonidos. Para lograr esto, necesitamos un sistema simple que verifique si la instancia de un evento existe o no. Usando una propiedad int32 y algunas técnicas de control de flujo, vamos a crear un algoritmo que verifique si una instancia existe, luego podremos Pausar/Continuar, Detenernos e Iniciar el evento de nuevo. Solo una instancia de este evento será reproducida a la vez.

IMPORTANTE:

Asigna el evento Play_MusicLoop" a la propiedad My Event.

Play Event:

Blueprint:

 

Right-click on the graph and search for: “Keyboard Event E“, "Get My Event Instance ID“, “Equal", “Branch“, “Get My Event", “Get A Reference To Self”, “Post Event", “Execute Action On Playing ID”, “Set My Event Instance”, and “Set Is Paused”.

 

.cpp file:

void AMyUE5ProjectCharacter::PlayEvent()
{
   if (!myEventInstanceID)
   {
	myEventInstanceID = UAkGameplayStatics::PostEvent(myEvent,
	    this, 0, FOnAkPostEventCallback());
		
	bIsPaused = false;
   }
   else
   {
	UAkGameplayStatics::ExecuteActionOnPlayingID(AkActionOnEventType::Resume,
	     myEventInstanceID, 0, EAkCurveInterpolation::Linear);
	
	bIsPaused = false;
   }
}

Parametros/Argumentos:

  • AKEvent (UAkAudioEvent*) = myEvent

    El evento Wwise a reproducir

  • Actor (AActor*) = this

    El actor en el mundo al que se le va a vincular el evento. Use this por defecto.

  • CallbackMask (int32 or enum AKCallbackType) = 0

    Este argumento define el tipo de callback en caso que este evento dispare una función callback. Usa 0 para None.

  • PostEventCallback (FOnAkPostEventCallback) = FOnAkPostEventCallback()

    Si este evento dispara una función callback, este argumento va a producir el delegado que va a disparar dicha función. Usa el constructor de la clase FOnAkPostEventCallback() para None.

  • bIsPaused (bool) = false

    Propiedad booleana para rastrear el estado de pausa de nuestro evento.

  • ActionType (enum) = AkActionOnEventType::Resume;

    Define el tipo de acción aplicada a este evento.

  • Event Instance ID (int32) = myEventInstanceID;

    El número de instancia de este evento.

  • Transition Duration (int32) = 0;

    La duración de la transición para aplicar esta acción en milisegundos. Usa 0 por defecto.

  • Fade Curve (enum) = EAkCurveInterpolation::Linear;

    El tipo de curva de interpolación aplicada a esta transición. Si de deja en blanco, Linear será en valor por defecto.


Pause Event:

Blueprint:

 

Right-click on the graph and search for: “Keyboard Event R“, “Get Is Paused, ”Get My Event Instance ID”, “Execute Action On Playing ID”, and “Set Is Paused”

 

.cpp file:

void AMyUE5ProjectCharacter::PauseEvent()
{
   if (!bIsPaused)
   {
	UAkGameplayStatics::ExecuteActionOnPlayingID(AkActionOnEventType::Pause,
	myEventInstanceID, 0, EAkCurveInterpolation::Linear);

	bIsPaused = true;
   }
}

Parametros/Argumentos:

  • ActionType (enum) = AkActionOnEventType::Pause;

    Define el tipo de acción aplicada a este evento.

  • Event Instance ID (int32) = myEventInstanceID;

    El número de instancia de este evento.

  • Transition Duration (int32) = 0;

    La duración de la transición para aplicar esta acción en milisegundos. Usa 0 por defecto.

  • Fade Curve (enum) = EAkCurveInterpolation::Linear;

    El tipo de curva de interpolación aplicada a esta transición. Si de deja en blanco, Linear será en valor por defecto.

  • bIsPaused (bool) = true

    Propiedad booleana para rastrear el estado de pausa de nuestro evento.


Stop Event:

Blueprint:

 

Right-click on the graph and search for: “Keyboard Event T“, ”Get My Event Instance ID”, “ Execute Action On Playing ID", “Set My Event Instance ID“, and “Set Is Paused”

 

.cpp file:

void AMyUE5ProjectCharacter::StopEvent()
{
   UAkGameplayStatics::ExecuteActionOnPlayingID(AkActionOnEventType::Stop,
	myEventInstanceID, 0, EAkCurveInterpolation::Linear);
	
   myEventInstanceID = 0;
   bIsPaused = false;
}

Parametros/Argumentos:

  • ActionType (enum) = AkActionOnEventType::Stop;

    Define el tipo de acción aplicada a este evento.

  • Event Instance ID (int32) = myEventInstanceID;

    El número de instancia de este evento.

  • Transition Duration (int32) = 0;

    La duración de la transición para aplicar esta acción en milisegundos. Usa 0 por defecto.

  • Fade Curve (enum) = EAkCurveInterpolation::Linear;

    El tipo de curva de interpolación aplicada a esta transición. Si de deja en blanco, Linear será en valor por defecto.

  • bIsPaused (bool) = true

    Propiedad booleana para rastrear el estado de pausa de nuestro evento.


.cpp file:

 
 

Blueprint Graph Completo:

 
 
 
 
 

Extra - Todo en C++?:

Si prefieres quedarte completamente en C++, Te mostraré como crear una referencia directa deI Wwise AudioEvent y cómo asignar teclas de tu teclado para disparar tus funciones.

Referencia directa a un asset o recurso:

Ve al Content Drawer y encuentra el evento del cual quieres una referencia, da click derecho en él y selecciona Copy Reference para obtener la ruta de tu evento.

 
 

Abre tu archivor .h, y pega la ruta en tu propiedad Wwise event dentro de TEXT(“ “) como un argumento:

.h file:

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Audio")
UAkAudioEvent* myEvent = LoadObject<UAkAudioEvent>(nullptr, TEXT("AkAudioEvent'/Game/WwiseAudio/Events/Default_Work_Unit/Play_OneShot.Play_OneShot'"));

Asignación De Teclas A Funciones:

Dentro del archivo .cpp, encuentra la función SetupPlayerInputController() y añade tus asignaciones de teclado aquí. Estas líneas de código logran lo mismo que llamar “Keyboard Events” en Blueprints al asignar las teclas E, R, y T a tus funciones PlayEvent(), PauseEvent(), y StopEvent().

.cpp file:

void AMyUE5ProjectCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
  PlayerInputComponent->BindKey("E", IE_Pressed, this, &AMyUE5ProjectCharacter::PlayEvent);
  PlayerInputComponent->BindKey("R", IE_Pressed, this, &AMyUE5ProjectCharacter::PauseEvent);
  PlayerInputComponent->BindKey("T", IE_Pressed, this, &AMyUE5ProjectCharacter::StopEvent);
}
 

El FIN!

〰️〰️〰️

El FIN! 〰️〰️〰️

Previous
Previous

Sistema de Pasos en Unreal Engine y FMOD (Blueprints y C++)

Next
Next

Eventos FMOD en Unreal Engine 5 (Play Event 2D) - Game Audio Basics