Interfaces en Unreal Engine (Para Game Audio)

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

Unreal Engine Version: 5.3.2

Este blog post muestra cómo crear y usar interfaces en Unreal Engine. También muestra cómo crear estas interfaces en C++ y Blueprint y cómo combinar los dos tipos. Para este prototipo, Implementé un notify de animación en el Player Character que llama a una función en su clase dueña usando una interface. También simulé una característica de juego en donde el radio de los sonidos de pasos dispara el estado de alerta en dos torres enemigas usando interfaces.

Para el sistema de pasos, usé solo scripting visual Blueprint. Creé el sistema de alerta en las torres dos veces usando blueprints y C++ nativo.

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

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! 〰️

Considera leer y consultar mi post anterior sobre UPROPERTY & UFUNCTION y Exponer Propiedades y Funciones C++ a Blueprints:

IMPORTANTE!

〰️

IMPORTANTE! 〰️

 

Pasos!

Implementar sonidos de pasos puede parecer muy típico y trivial, pero es muy conveniente para mostrar el uso de interfaces. El primer paso es importar una collección de Sound Wave .uasset

Creé un Metasound Source .uasset que dispara estos sonidos de manera procedural. Este graph metasound selecciona un sonido random, añade una variación de pitch dentro de un rango de valores, y finalmente reproduce el sonido.

Interfaces

Una interface es un tipo dentro de la programación orientada a objetos que permite la comunicación entre clases que no tienen relación. Contienen una colección de funciones declaradas por el usuario más ninguna definición, dejando así que cada clase que implemente dicha interface pueda definir sus propias funciones localmente. Otro beneficio es que las clases que interactuen no necesitan saber el tipo de la otra; siempre y cuando estas implementen la interface, la existencia de las funciones está garantizada. Quiere decir que no hay necesidad de hacer ningún casting.

Footsteps BP Interface

Animation Notify y Blueprint Interface

Para este primer ejemplo. Implementé un sistema de pasos simple creando un nuevo Animation Notify llamado AnimNotify_FS.

Antes de añadir la funcionalidad de este Notify, Creé una interface Blueprint llamada BPI_FS.

Dentro de la interface BPI_FS, Declaré una función llamada Play Footstep que acepta dos parámetros: el primero obtiene el nombre del hueso (Bone) o socket en el skeletal mesh, y el segundo es el radio de interacción. Nota que no hay opción de crear nada dentro del graph porque esta función es de Solo Lectura.

De regreso a AnimNotify_FS, Añadí dos variables públicas que imitan los mismos parámetros que la función Play Footstep: Bone e Interact Radius. Estas me permiten proveer estos valores dentro del secuenciador de animación.

En AnimNotify_FS, sobreescribí la función Received Notify, y definí esta funcionalidad:

Cómo puedes ver al seguir el proceso, la función Receive Notify obtiene una referencia al mesh component, verifica que su dueño implemente la interface BPI_FS, y si es verdad, llama a la función Play Footstep en este.

NOTA: Las funciones declaradas en interfaces son de accesso global en Blueprint, entonces aparecen en el menú “All Actions For Blueprint” al dar click derecho en el graph.

Secuencias de Animación

El siguiente paso es marcar las secuencias de animación de caminar y correr con el nuevo Notify. Es posible encontrar todos los notifies de animación al dar click derecho en el timeline.

Después de marcar las secuencias de animación, el proveer el nombre del hueso es necesario. Esto es esencial para reproducir sonido e interacción desde la posición correcta. Para lograr esto, selecciona cada notify en el timeline y llena el campo Bone con el nombre correcto del hueso.

Implementación de la interface BPI_FS en el jugador

Para poder implementar BPI_FS en el jugador, abrí el BP_TopDownCharacter y di click en Class Settings. Encuentra la interface BPI_FS y añádela a la lista.

Una nueva categoría de interfaces aparece debajo de“My Blueprint." Al dar click derecho y seleccionar Implement Event este evento será creado en el graph.

Audio Interact Interface C++

IAudioInteract

Para este sistema, creé una interface C++ llamada Audio Interact. Para añadirla a nuestro código fuente, abre el content browser, da click derecho en la sección C++ classes, y selecciona New C++ class.

Dentro de la interface, debajo de la clase IAudioInteract, Declaré una función AudioInteract() que recive al actor que llama a esta función, o instigador (instigator). Añadí BlueprintNativeEvent para permitir a Blueprint sobreescribir o extender esta función. BlueprintCallable le permite a Blueprint llamar a esta función.

Llamar a Audio Interact desde el jugador

Para implementar mi nueva interface en C++ en el jugador, definí otra función llamada OnPlayFootstepCPP() que acepta el nombre del hueso (Bone) y el radio de interacción como parámetros. Adicionalmente, Añadí un campo para proveer a mi personaje con el sonido de pasos.

MyUE5ProjectCharacter.h

Para obtener la interfae AudioInterct, añade:
#include "AudioInteract.h"

MyUE5ProjectCharacter.cpp

Así es como la implementación de ve en Blueprint

IAudioInteract en las torres enemigas

Para probar la interaciión y comunicación de la interface IAudioInteract, Cree dos clases de torres enemigas, una Blueprint y otra C++. Estas torres reproducen un sonido de alarma, y su color emisivo oscila when interactuan con el radio de los pasos. La torre de color azul se llama BP_EnemyTurret_BpOnly, y la torre roja se llama BP_EnemyTurret_CPP y hereda de la clase C++ Enemy Turret.

Para obtener el efecto visual deseado, definí un parámetro llamado OscMultiplier en el material. El script Blueprint o el código C++ van a definir este parámetro.

Torre Enemiga Blueprint

BP_EnemyTurret_BpOnly implementa la interface directamente.

Así es como se ve la definición de Audio Interact en el Blueprint.

Torre Enemiga C++

Para implementar una interface en C++, es esencial añadir estas líneas en la declaración de la clase. En este caso, AEnemyTurretCPP hereda de AActor y también de IAudioInteract

EnemyTurrretCPP.h

Declaré la función de la interface IAudioInteract y todos los parámetros requeridos por el sistema.

EnemyTurrretCPP.h

Esta es la definición de Audio Interact en el archivo .cpp. Fíjate que su nombre es distinto AudioInteract_Implementation(); esta es la convención cuando una función es de tipo BlueprintNativeEvent. Para este sistema, escribí parte de la funcionalidad en C++ y la extendí en su hijo.

EnemyTurrretCPP.cpp

BP_EnemyTurret_CPPChild

 

THE END

〰️〰️〰️

THE END 〰️〰️〰️

Previous
Previous

Post MIDI On Event en Wwise y Unreal Engine

Next
Next

Audio Listener 2D Para Música y UI en Unreal Engine y Wwise