Create a Strafing System in Unreal Engine
As part of our new Unreal Engine development series, we are going to be releasing our project files for different types of complex systems that also include the simple animations that are featured in the systems for prototyping as well.
It's our way of giving back to the great community that supports the Unreal Engine.
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.
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 onto 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 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 seperately 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 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 the what the InputAxis Forward connects into. 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 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 a rotation movement over time, we can use the RInterp To node. This node requires 4 things:
A Target Rotation to turn to
3 and 4 and both simple, 3 we can use Get World Delta Seconds and the Interp Speed we want the character to rotate smootly 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 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 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 animations blendspace 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" and 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 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 blendspace).
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 re-named to something appropriate (I used InputXAnim and InputZAnim.)
We just need to dive into our AnimGraph and hook up the blendspace with the values we recieved from the CustomCharacter blueprint and synced with the animation blueprint.
Above is the where we set up the names for the 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 smoothness of our controller and stop the blendspace from adjusting between animations to 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 is Strafe as this is what the blendspace that we will hook up contains.
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:
Completed controller in action
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 below to test it out for yourself.
Download the System Here: