Interfaces in Unreal Engine (For Game Audio)

Si prefieres leer una versión en Español, da click en este botón =>

Unreal Engine Version: 5.3.2

This blog post shows how to create and use Interfaces in Unreal Engine. It also shows how to create these interfaces in C++ and Blueprint and combine both types. For this prototype, I implemented a footstep animation notify on the Player Character that calls a function on its owner using an interface. I also simulated a gameplay feature where the sound radius of the footstep sounds triggers an alert state on two different enemy towers by using interfaces.

For the footstep system, I used a Blueprint visual scripting-only implementation. I created the same system twice for the tower alert part, using blueprints and native C++. Here is the list of essential tools and keywords used for this project:

Important:

Please consider that this guide does not intend to teach creative sound design. Instead, it exclusively focuses on game audio's implementation and programming aspects.


Download the project here:

IMPORTANT!

〰️

IMPORTANT! 〰️

Please consider reading and referencing my previous post about UPROPERTY & UFUNCTION and Expose Properties and Function to Blueprints:

IMPORTANT!

〰️

IMPORTANT! 〰️

 

Footstep Sounds!

Implementing footstep sounds in Game Audio might seem ubiquitous and trivial, but it is convenient to show the use of interfaces. The first step is to import an array of Sound Wave .uasset

I created a simple Metasound Source .uasset that procedurally triggers these sounds. This metasound graph picks random sounds, applies a pitch variation in a range of values, and then outputs the sound.

Interfaces

An interface is an object-oriented programming type that allows unrelated classes to communicate. It carries a collection of user-defined function declarations but no function definitions, allowing every class that implements a determined interface to define its functions internally. Another benefit is that the interacting classes don’t need to know each other types; as long as they implement the interface, it is ensured that the functions exist, so there is no need for type casting.

Footsteps BP Interface

Animation Notify and Blueprint Interface

For the first example, I implemented a simple footstep system by creating a custom Animation Notify called AnimNotify_FS.

Before adding this Notify functionality, I created a Blueprint Interface called BPI_FS.

Inside the BPI_FS interface, I declared a function called Play Footstep that accepts two parameter inputs: the first gets the name of a bone or socket in the skeletal mesh, and the second is an interaction radius. Notice there is no option to create anything inside the graph because this function is Read-Only.

Back at the AnimNotify_FS, I added two public variables that mirror the same parameters of the Play Footstep function: Bone and Interact Radius. This allows me to input these values into the animation sequencer.

Back on the AnimNotify_FS, I overrode the Received Notify function, and implemented this functionality:

As you can see by following the process, the Receive Notify function gets a reference to the mesh component, asks if its owner implements the BPI_FS interface, and, if it does, calls the Play Footstep function defined in the owner.

NOTE: Functions declared in interfaces are globally accessible in Blueprint, so they appear in the “All Actions For Blueprint” menu when right-clicking on the graph.

Animation Sequences

The next step is to tag the walking and running animation sequences with the custom-created notify. You can find all animation notifies in the animation sequencer by right-clicking on the timeline.

After tagging the animation sequence, providing the Bone Name parameter is necessary. This is essential to spawn sound and interaction from the correct emitter position. To achieve this, select each notify on the timeline and fill the Bone field with the correct bone name.

BPI_FS Interface Implementation on the Player Character

In order to implement the BPI_FS interface in the player character, I opened the BP_TopDownCharacter and clicked on Class Settings. Find the BPI_FS interface and add it to the list.

Next, a new interfaces category appears under “My Blueprint." Right-clicking and selecting Implement Event will create the function in the graph.

Audio Interact C++ Interface

IAudioInteract

For this system, I created a C++ interface called Audio Interact. To add this to the source code, open the content browser, right-click in the C++ classes section, and select New C++ class.

Inside the interface, under the IAudioInteract class, I declared an AudioInteract() function that receives the actor that calls this function, or instigator. I added the BlueprintNativeEvent specifier to allow Blueprint to override or extend this function. The BlueprintCallable specifier enables Blueprints to call this function.

Calling Audio Interact from the Player Character

To implement my new C++ interface on the player character, I defined another function called OnPlayFootstepCPP() that accepts a Bone name and a radius as parameters. Additionally, I added a field to provide my character with the footstep sound.

MyUE5ProjectCharacter.h

To get the AudioInterct interface, add
#include "AudioInteract.h"

MyUE5ProjectCharacter.cpp

This is how the same implementation looks in Blueprint

IAudioInteract on Enemy Turrets

To test the interaction and communication of the IAudioInteract interface, I created two Enemy turret classes, a Blueprint and a C++ one. These turrets play an alarm sound, and their emissive color oscillates when interacting with the footstep sound radius. The blue tower is called BP_EnemyTurret_BpOnly, and the red tower is called BP_EnemyTurret_CPP and inherits from the Enemy Turret C++ class.

To achieve the desired visual effect, I set an OscMultiplier parameter on their material. The BP script or C++ code will set this parameter.

Blueprint Enemy Turret

BP_EnemyTurret_BpOnly implements the Audio Interact interface directly.

This is how the definition for Audio Interact looks in Blueprint.

C++ Enemy Turret

To implement an interface in C++, adding these lines to the class declaration is essential. In this case, AEnemyTurretCPP inherits from AActor and also from IAudioInteract

EnemyTurrretCPP.h

I declared the function from the IAudioInteract interface and all the parameters required for the system.

EnemyTurrretCPP.h

This is the definition of Audio Interact in the .cpp file. Notice that it is named AudioInteract_Implementation(); this is the convention when a function is a BlueprintNativeEvent. For this system, I wrote part of the functionality in C++ and extended it in the child Blueprint.

EnemyTurrretCPP.cpp

BP_EnemyTurret_CPPChild

 

THE END

〰️〰️〰️

THE END 〰️〰️〰️

Previous
Previous

Post MIDI On Event in Wwise and Unreal Engine

Next
Next

2D Audio Listener for Music and UI in Unreal Engine and Wwise