In this tutorial I’ll talk through the process I used to introduce footstep noises to the player character, using Blueprints – as part of my first VR release “The Caretaker” (free to download on Oculus Share). Audio is a fantastic tool in a developer’s tool-kit that can really contribute to a convincing experience in VR – giving the player grounding in the world you’ve created, and greatly enhancing their immersion.
It turns out that this is straightforward using UE4 blueprints. Here’s a look at the approach I used for the First Person Character Blueprint – I expect there are better ways out there to achieve this, but this was quick to add, and pretty convincing.
The Blueprint Basics
Here’s what we want our system to do:
- We want to track what the player is walking on, by detecting the surface type below the player’s feet.
- We want to play footstep sound based on the surface type detected, at the point of contact of the player’s feet and the floor.
- We want the frequency of the player’s footsteps to speed up and slow down as they increase or decrease speed in-game.
- My first person character doesn’t have a player-model; so the footsteps would need to run on some sort of timer, rather than being tied in with animation notifies.
Setting up Surface Types
Unreal Engine 4 allows one to associate physical material types with shaders – so a snowy material can tell other systems what it’s made of (snow I guess); a wooden floor can be categorised as wood, and a cheesy material can behave more cheesily when interacted with; say if you wanted to model the lunar surface.
In order to do this, we first need to let UE4 know what material types feature in the level. In this instance, I was really only interested in the flooring materials.
To add new surface materials to your project:
- Go to your project’s Edit > Project Settings Screen
- Navigate to the Physics section
- Type in the different surface types you want to model in your project. For mine, this was Carpet, Snow and Tiles. Exit the Project Settings screen.
Next, we’ll need to set up some “Physical Materials” which will refer to the surface types we added to our project settings, and then assign them to our floor materials.
Head to your content browser, right-click and add Physics > Physical Material. Create and name a physical material for each surface type you added in the previous step.
Once this is done, open each physical material in turn, and select the corresponding surface type in the Physical Properties > Surface Type drop-down. Save each and exit them.
Applying Physical Materials to Your Shaders
Next, we want to assign Physical Materials to our flooring materials, so that we can query them when each foot-step falls.
Open each flooring material, and in its details panel (bottom left by default), select the right physical material from the drop-down menu, and save.
Setting Up Audio Cues
For my footstep sounds, I used free audio from the fantastical Freesound.org, picking sequences which included many footfalls.
I wanted some variance in the footsteps from each footstep to the next – just to make things sound a little more natural, so I grabbed around 6-8 different footstep sounds per surface type; extracting the individual footfalls from any given footstep sequence, saving to .WAV and importing to the content browser. I used the free audio editor “Audacity” for this.
Once you’ve done the same, it’s time to set up your cues. Right click on your content browser, and create a new Audio > Sound Cue. Name it [surface_type]_footsteps_cue – or a naming convention of your own. We’ll make one cue per surface type.
Open the sound cue, and drag all of this surface type’s audio into the sound cue. For my carpet footstep cue, I had 8 audio clips (probably more than is needed) – each a single footfall.
Add a “Random” node and plug each step into it. This will make sure that a random footstep from the selection will be played when triggered. Add a modulator between the “Random” and “Output” node to introduce yet more variance to the sound.
The effect of this is that the footsteps will feature less repetition, which can make things feel more natural.
Repeat this process for each surface type – making a new sound cue for each.
What has the player stepped on?
Now that we’ve got our surfaces and audio cues set up, it’s time to join the dots with our Player Character.
Firstly, we want to find a way of detecting the surface type the player is walking over. We do this by running a line-trace from the player character to the surface below, and querying the material it hits.
Rather than running this every tick, we really only need to do this every time a footstep noise is needed; and then, only when the player is moving at a minimum speed. People who are creeping around don’t make as much sound as someone who’s walking at full pace. Open your player character blueprint (mine is based on the FirstPersonCharacter), and create a new function (just above the “Variables” panel). I called mine “Footstep”.
Take a look at the complete Blueprint below, and I’ll talk through what each section does. Check out the layout of my “Footstep” function below.
- I only want to play footstep sounds if the user is moving at a certain pace. Take the player’s movement component, and get the ‘length’ of its ‘velocity’ vector. Here, if the player’s velocity is above 40, the function may proceed. This also stops the footstep audio from continuing if the user is walking against an obstacle – such as a wall.
- Now that we know the player is moving at a fast enough space, we take the position of the player, and fire a line trace 500 units below; which is more than enough to hit the ground. We feed the line trace’s “Actors to Ignore” input an array containing the player character, just so we don’t immediately collide with the player.
- We query the surface type of the object hit by the line trace, and using that as the input to a select node, choose the correct audio cue to play at the impact location. The select takes an input, and allows one to switch the output based on its value.
Next we need a way to regulate calls to our Footprint function.
Taking First Steps
In a third-person game – or with an AI character, one could call our footstep function via animation notifies (to read up on these, check the official documentation here). This would sync up audio perfectly with character animation.
In my case, the player doesn’t have a body as such – they are simply a floating head and collision capsule. For my solution, I created a looping timeline which drives the footstep function, whose rate of play changes based on the player’s movement rate. When the player is at a complete stop, the play rate will decrease to zero, while at full speed, it’ll play at its full rate.
Firstly, let’s set up the footstep timeline. Open your Player Character Blueprint, and on the event graph, right click and add a new timeline. I called mine “FootstepTimeline”.
Open the timeline by double clicking, then:
- Add an event track (marked with a !).
- Change the length of the timeline to the full length of your walking cycle – mine was 1 second – yours may be faster or slower.
- Check the “Loop” and “Autoplay” check-boxes.
- Name the new event track “FootstepEvent”, or something easy to remember.
- Add two points on the event track, one at 0 seconds, and the next halfway through the cycle. These will be the points at which the Footstep function is called.
Save the timeline and switch back to the event graph.
Next, we’ll get the timeline running at the start of play. Take a look at the Blueprint setup below. At the start of play, we take a reference to the timeline we created, set its play rate to 0 (effectively stopping it), and then get it running. Linked to our Footstep Event output, we call our footstep function, which we put together earlier.
This now means that when we change the play-rate of the timeline from somewhere else, we can start, stop and vary the speed of footsteps.
We’re almost there! The final step is to link the play-rate of our timeline to the player’s forward and backward movement. In your Player Character event graph, locate the movement input section. We want the InputAxis Moveforward node.
Take a look at the blueprint setup below, and set up yours in the same way.
The Axis Value output from the Moveforward node gives us a value from -1 to 1, where -1 is walking full backwards, 1 is full forwards. When stationary, the value will remain at 0. When a player moves forward on their controller, this value will change gradually from 0 to 1 as they speed up.
Linking this first to an Abs node will turn any negative values to positive, which means we’ll always get a value from 0 to 1, regardless of whether the user is walking forwards or backwards. This can then be used to set the New Rate input of the “Set Play Rate” node.
The net effect is that when the player moves forward, the play-rate of the footstep timeline will increase, firing footsteps regularly as they traverse the level. We’re done!
You may wish to tweak values such as the timeline length to better suit the walking speed of your character. Thanks for reading through this tutorial – I hope it was of use!
If you found this useful, please consider tweeting about it or leaving a comment below. If you’ve any thoughts on better approaches, they would be welcome too! I’ll do my best to answer any queries below.