Creating a Strafe Movement System in Unreal Engine

Learn how to create and setup your own strafe movement system in Unreal Engine

Written by Kieren Hovasapian

Today, we are going to be releasing some sample project files for setting up a strafe movement system that also include the simple animations that are featured in the system for prototyping as well.

Please Note: This project was built using engine version 4.19. There shouldn't be any problems upgrading it to a newer engine as most of the underlying functions are present in the engine.

Introduction

We started by importing our animations that were created in 3ds Max on our super simple rig called RigMan! This allows us to create rapid iterations of our systems and try to implement many different techniques and movements.

For this project, we created a quick 360 range of movement designed especially for a strafe system - this was a design decision as we knew we were going to use a Blendspace to handle the strafe movement. To be precise there are exactly 9 animations required for this type of system as a minimum to give us the best results.

Animation List:

  • Move Forward. 
  • Move Backward. 
  • Idle. 
  • Move Left. 
  • Move Right. 
  • Move Left Forward (-45 degrees). 
  • Move Right Forward (45 degrees).
  • Move Left Backward (-135 degrees). 
  • Move Right Backward (135 degrees).

Implementing the Animations

Now we can move on to connecting up our blueprint for the character. This blueprint is called: CustomCharacter.

Setup the Blueprint

First, we will have a look at the component settings that are in use for a strafe system. Below is a screenshot of a standard character setup in Unreal.

Under CustomCharacter(self) make sure the Use Controller Rotation Yaw is unchecked - we will handle the rotation separately in the Blueprint.

The reason for handling the Use Controller Rotation Yaw separately is due to the snapping it provides when moving after idling. Instead, we will create a smooth RInterp To node that will grab the Control Rotation's Yaw and then blend over time to that new rotation - which is the direction we want the character to face for correctly strafing.

Nothing was altered for the rest of the default settings in the CapsuleComponent, Mesh, and CharacterMovement (inherited) components.

Now let's have a look at the structure of the blueprint itself.

Below is what the InputAxis Forward connects to. First, we set the InputMagnitude or how much the player is pressing the stick/button. We do this by getting the absolute values of both the input forward axis and right axis and then adding them together. However, now if you move the stick/buttons diagonally you could potentially get 2 which would increase the speed of the character past our desired maximum of 1. So we just need to create a clamp between a minimum of 0 and a maximum of 1 and set that to a promoted variable called the InputMagnitude.You can set after the InputMagnitude variable has been set we have a branch that is controlled by that created InputMagnitude. When the InputMagnitude is greater than (>) 0.1 we can allow the branch to continue executing which will allow the player to turn to the correct camera forward-facing rotation (this is calculated from the small function connected to the NewRotation on the SetWorldRotation node.)We know that we want the character to face the camera forward position, so since this is a rotation movement over time, we can use the RInterp To node.

This node requires 4 things:

  • Current Rotation
  • A Target Rotation to turn towards
  • Delta Time
  • Interpolation Speed

3 and 4 and both simple, 3 we can use Get World Delta Seconds and the Interp Speed we want the character to rotate smoothly but not too quickly, a value of 3.4 should do nicely (feel free to adjust if you want more snappy or slower movement).

For the current rotation (1) we want to our character's Capsule Component's world rotation. This is just a simple GetWorldRotation which connects to the Capsule Component reference.

Our target rotation (2) will be the Control Rotation, luckily there is also a built-in function node for us to use called GetControlRotation, right mouse click of the rotation output and split the struct and you'll have access to 3 different pins. We need to use the Return Value Z (Yaw) pin. Take that and plug it into the Target Z (Yaw) of the RInterp To node. Now the RInterp To node is ready - grab the return value and plug it into the SetWorldRotation node down the chain.

Again our target is the CapsuleComponent as this is what we want to rotate.

That's the hard part of the blueprint done.

We also need to set up our simple camera movement controls - this is just the standard movement control setup that comes in the third-person project files. I have taken a screenshot just in case you need it.

Animation Blueprint - The Final Steps

Now that we have made the blueprint for our CustomCharacter let's move on and finish up by creating our animation blueprint which will get the InputX and InputZ values that we stored for our movement inputs and sync them for the animation blend space to operate.

To set up our Animation Blueprint we start with the Event Blueprint Update Animation (this should be present if you are opening the blueprint for the first time anyway). Next, we create an IsValid node with the Input Object of Try Get Pawn Owner - this ensures that if we can get the pawn owner that the connection "Is Valid" we can continue the logic.

Now we need to drag out from the Try Get Pawn Owner node and create a new Get Movement Component and Is Falling node. For this, we are actually using the Is Falling but it's handy to have set up in any case. Finally again from the Try Get Pawn Owner node we drag out a new connection and find the Blueprint which we just created, typically this is how we can access variables we have created in the Blueprint. We want to look for the Cast To CustomCharacter node - this will give us the capability to get our variables now.

You'll notice in between our IsValid and Cast To nodes we have a set "Is Falling?" node. This is how we store the boolean for if the player is in fact falling or not falling (yes / no). The best way to create this node is to drag from the return value of the Is Falling node and say Promote to Variable and then call it "Is Falling?".Connect the IsValid true to the set IsFalling? variable and then continue the flow to connect to the Cast To CustomCharacter node. Now from the CustomCharacter node, we need to drag out from As CustomCharacter and get the two variables from our blueprint - Get InputX and Get InputZ (or our vertical and horizontal movement which we will feed into the blend space).

Once we have those two nodes again, we will create two Promote to Variables for both the InputX and InputZ variables. After these have been made and renamed to something appropriate (I used InputXAnim and InputZAnim.)

Almost there!

We just need to dive into our AnimGraph and hook up the blend space with the values we received from the CustomCharacter blueprint and synced with the animation blueprint.

Above is where we set up the names for each Axis - the first "InputX" is left to right (horizontal) and the second "InputZ" is forward and backward. You might notice I have also adjusted the Interpolation Time on both to 0.5 as well - this will increase the smoothness of our controller and stop the blend space from adjusting between animations too quickly.

Okay, so we have now moved over into the Anim Graph, and as you can see I right mouse clicked on the graph and searched for "Add New State Machine" and after you create that rename it something like Locomotion and connect Figure to the Figure Result (Final Animation Pose).

Now if we double click on the state machine that we dive inside it and we need to set up the state to connect to the Entry node. If you drag off the Entry node's arrow you'll have two options, Add Conduit and Add State - we need to create a new state so let's go with Add State and we will name it Strafe as this is what the blend space that we will hook up contains.

Inside the Strafe State, we connect the blend space to the variables we have created previously.

In the final step, if we right mouse click on the grid again and search for our Blendspace called StrafeBS this will place that node that we can connect the figure to the figure result. Now we can drag the two variables, "InputXAnim" and "InputZAnim" each into their respective slots that we set up in the Blendspace before.

That's it! We have now finished the system and we can press play, this will compile the blueprint (checking for errors) and then open the player window.

We will now have the Strafe controller that will be playable like this:

Now we have completed this controller and have successfully tested it.

Now we can continue this system by refining the animations and building an aiming and damage system in the next tutorial.

Thank you for taking the time to read this and if it helped or you have any questions please let us know in the comments below.

Also, you can download the finished system from our store for free to test it out for yourself from the Asset Area