How to make a first person wall run in UE4
Author: Jamie Wilson
Introduction
This tutorial is not suitable for a beginner user of Unreal Engine and assumes you have solid knowledge of the basics.
You are needing a wall run system for your game similar to Mirror’s edge but you don’t know where to start? We will be going through how to do this below. This tutorial is for UE4 blueprints but should be easily transferable into UE5, c++ or even a different engine. It will also be be pretty much the same implementation in third person.
If you don’t have time to follow the tutorial and want to skip straight to the code. You can find it at the bottom of the page.
Getting Started
For this tutorial we will be starting from the First Person Example Project (we are using UE4.26).
Once you have the project open. Open the FirstPersonCharacter blueprint (located FirstPersonBP/Blueprints) we will be putting all the code for the wall run in here.
First up we need to detect when there is a wall to run on. To do this we are going to run a check “On Tick” to see if there is an appropriate wall to run on and if the player is in right state. The first checks we want to run are 1. is the player in the air and 2. what objects are around the player.
We can get the Character movement and get “Is Falling” this will let us know if the character is in the air. Then to see what objects are around the player we can do a “Sphere Trace For Objects” which will return the closest object in the trace only. The trace needs to be larger than the players capsule how much larger is up to you we are going 35 bigger. We use two vectors for start and end to define the size this should be X+ and X- (in our case +-50) the capsule location to center the sphere on the player. We also will plug in a “Make Array” node with “World Dynamic” and “World Static” to the object types to filter out non wall assets such as Enemies. Then “Break Hit Result” to get hit objects info.
Now we have all the objects in the players vicinity while the player is in the air. We now have to filter them to determine which are walls. To do this we will get the surface normals (at the sphere trace impact location), break out the z component (z will be 0 if wall is vertical and 1/-1 if horizontal). Then we test that value against what we want to allow if you only want to allow perfectly vertical walls just check if it is = 0 in our case we are going to allow -0.28 overhang (this is should be less than or equal to the z) and a 0.71 incline (this should be greater than or equal to z). Use an and node to combine these results so that we are left with only walls within this range. I also added an and condition to see if the sphere trace returned an object (this should be done as the first condition in the and to prevent the second condition being checked if there is no object).
We have now checked all the conditions about if the wall is suitable. You can also check the players state to see if they are in an appropriate state (e.g. looking in a certain direction or going a particular speed) but for now we are going to move on to the implementation of the wall run. First up we need to get the direction that we want to wall run in. To do this we will be using the player’s velocity and the wall’s normal to work this out. The first part is working out if the wall is on the left or the right of the players velocity vector. To do this get the look at rotation of the velocity from the origin and the wall normal from the origin. The sign of the z component of the delta between these rotations will give us the direction (positive on the right, negative on the left). Multiplying this by 90deg and making it into a rotator will allow us to rotate the wall’s normal to give us a normalised vector which points in the direction we want to move along the wall. We can then save this result into a variable.
After calculating the wall run direction we need to see if a wall run is already in progress. Make sure the wall running Boolean is defaulted to false. By doing this check after the wall run direction calculation it will mean that the wall run will work on curved surfaces.
Everything after this will now only run when the wall run is initialised. First part of the initialisation is to record the player’s initiation speed. After that we want to set up a timer to move the player along the wall (you could do this on tick but isn’t required so we might as well run it less often).
Now we have a fantastic wall run that will move you along surfaces. However, you can’t stop it and it goes on forever so lets fix that now. First up we want to define an event “Stop Wall Run” which we can call in various circumstances such as the player jumping off to end the wall run. In this event we need to reset “Wall Running” to false and “Clear and invalidate timer by handle” for the “Wall Run Timer Handle” and save the current game time. We can start by calling this event when the player jumps to let them off the wall.
We also need to add a check if x time has passed since a wall run has finished before we allow a new one. This should be added in just after the check for is player falling at the start of event tick. The value I am using for “Repeat Wall Run Delay” is 0.5s as this doesn’t really hinder the players interaction.
So now the player can jump off the wall (at the moment it should be more of a fall) but the wall run still goes on forever so lets fix that. The basic idea of what we want to do is slow down the player across their wall run and eventually drop them off. We are going to expand the code we put in the timer to achieve this. Basically we want to add in friction to the wall run this will come after the code for moving the player along the wall. Basically you want to multiply the wall run speed by a friction value in the case I first divide 1 by the “Wall Run Friction” variable this allows for a more human readable value for the friction i.e. above 1.0 not below it (I used 1.008). You then set the wall run speed to equal the result of the multiply. We then follow this up with a check to see if the current speed is below a certain threshold and if it is we call “Stop Wall Run”. At this point I updated the Character Movement speed from it’s slow 600 to a faster 900.
And that’s the functional implementation of the wall run complete. Optionally you can add your own jump code to make the player jump off the wall rather than just dropping off when they press “Jump” whilst on the wall. See below for where you should put this.
Lastly, we are going to add some cosmetic camera tilt. To do this lets create a custom event for the camera tilt. In this event we are going to use a timeline to smoothly animate the camera tilting. Use a sequence not to update the initial camera tilt to the current value then connect this up to the stop node in the timeline. From the second pin of the sequence connect us to “Play From Start” on the timeline. Next up fill the timeline as below. Then we need to use the timeline output as the alpha for a lerp between “Cam Start Tilt” and the event pin “Target Tilt”. We then use this value to add controller roll input and update the “Current Cam Tilt”.
Lastly we need to call our “Tilt Cam” event in the wall run initialisation (just after setting the player speed) using the result of “Sign (float)” from the Wall Run direction calculation. We also call the event in the “Stop Wall Run” event setting the target tilt to 0 and the sign to “Cam Tilt Sign”
AND that’s it! Thanks for following along :) I hope you found the tutorial helpful and if you would like access to the full source code used to create it you can get that below! If you have any questions you can ask them on our Discord server.
Edit: Fix for bug where wall run continues beyond the wall at the bottom (Project code contains fix)
Fixes
Basically we just need to call the “Stop Wall Run” event if the sphere trace doesn’t hit any walls (If there are no walls the player can’t run on them)