ADVANCED LOCOMOTION SYSTEM V2
June 29, 2017
Note From the Creator
First off, thank you for purchasing this system! As a self taught animator with a passion for game animation and character locomotion, I’ve given this project a lot of careful time and thought, so I hope that it meets your needs or at least gets you started.
I have tried to keep things as simple as possible, so people with limited programming knowledge should still be able to grasp the basic concepts and understand the “whys” of this system and its features. Please feel free to improve upon this system as you see fit. As I am primarily an animator, Some of the things demonstrated here may differ from the way an experienced programmer might do them. However, thanks to Blueprint, the basic fundamentals and logic flow of the system are all there.
I am super excited to see what people create using some of my work!
Thanks, and have fun :)
P.S. Don’t forget to leave a rating on the store page, the feedback always helps.
Too often game animation lacks quality due to the underlying movement and animation systems being poorly thought out. Animators can create good looking assets, but a badly designed animation graph can diminish their quality and create a sub-par experience. My motivation and purpose for this system is to bridge the gap between the front end and back end of in-game animation, and give animators a good foundation to create assets that will work well with character movement. This system demonstrates a method for achieving responsive movement while retaining a high level of animation quality.
The ideas and goals for this system developed naturally over time. Some of my main goals and focus points are listed below.
I wanted to create a system that:
Please keep in mind that this system was originally intended to serve as a template (or foundation) for animators who could create their own animations to work with this system. It is not a full game with tons of features, but it is a good starting point to build off of. It is also not a simple ‘plug and play’ system. Due to the complex nature of skeletal assets and gameplay animation, there will always be some additional work required to tweak the system to fit your animation needs.
Below you will find an overview of the Character Blueprint, Component, both the Anim Blueprint’s Event Graph and Animation Graph, as well as a breakdown of certain systems and how they work (images included). Not every individual blueprint node or function will be explained, as I am focusing on the “whys” (why something is there) and the “what's” (what is its purpose and what does it do). Whatever is left unexplained is either basic math or can be figured out relatively easily. Other tips and tricks are also mentioned throughout. Please follow along in the engine as you read, and I recommend you read everything thoroughly in order to have a good understanding of the system, so that you can adjust, modify, and expand on it to best suit your needs. Don’t forget to refer to the contents to find a specific section.
The system is primarily made up of three different parts. The CharacterBP, the AnimBP, and the Component. The CharacterBP is responsible for handling things related to a specific character, like player input, and camera management. The AnimBP is responsible for determining which animations should be playing at any given time, and for rotating the character. The Component acts as the middleman between the CharacterBP and AnimBP, but is also responsible for player movement, and handling important logic that is not directly tied to a specific character. The Component can be used on any number of characters, and is not dependent on a specific CharacterBP or AnimBP to work correctly. Each part has been designed to function separately, so they are not dependent on one specific BP (except the TurnInPlace_AnimNotifyState). This makes it easier to change AnimBPs, or CharacterBPs, without having to replace a bunch of references. I also make good use of Enums throughout this system. It helps to keep things organized, and can make it very easy to add new features without interfering too much with existing logic.
This system uses various curve assets for turning in place. See See Turn In Place Breakdown for more details on how they are used.
Enums are used extensively throughout the whole system, and serve to make the system highly flexible and easy to expand upon.
This enum is used in the Custom Rotation macros within the AnimBP. They define which cardinal direction the character is moving in so rotation offsets can be applied.
Custom Movement Modes
This enum contains names for custom movement modes. Because the Character Movement Component returns a byte when getting the Custom Movement Mode, I keep things more organized by converting the byte into an enum. The names simply represent a byte value, None being 0, and Ragdoll being 1. The next name you add will be Custom Movement Mode 2, etc.
Idle Entry State
This enum is used within the Anim Graph’s Idle State Machine, and determines which Idle state to blend into first. This is useful, when a certain animation (like a get up animation for example) ends in a certain Idle pose, but the character should be in a different one.
This enum is one of the most widely used enums throughout the whole system, and makes the character behave and rotate differently. It was intended to act as a placeholder for custom locomotion states. By default, State_1 makes the character behave like a traditional 3rd person adventure game. State_2 acts as an over the shoulder 3rd person game (character looking in camera direction) and doubles as a true first person mode. And State_3 functions as a Combat or Aiming state, making the character move more slowly and face the camera. Depending on your game, you could use all of these, or none of these, or create your own. For example, you could have a Locomotion State called navigation, in which the character can run around normally, like State 1. Then, if the character gets near an enemy, it could switch to a Combat Locomotion State where the character always faces the nearest enemy. It's all up to the design of your game in determining how these can be used.
This enum is set in the Custom Rotation macros in the AnimBP and determines which locomotion blendspace is used during Locomotion State 1 and 2. Having two blendspaces, one with the hips facing forward while moving side to side, and the other facing backwards, greatly improves blending and can eliminate the persisten foot crossing issue found in some strafing blendspaces.
This Enum determines which Rotation method the AnimBP should use. Turn In Place is a more realistic rotating method, but is not that responsive while turning the camera fast. Rotate In Place is a more responsive rotating method, and keeps the character facing the camera even during quick camera movements. Both of these methods can be used in first or third person, but by default, third person uses Turn In Place and first person uses Rotate In Place.
This enum simply represents the view mode. It is used in the CharacterBP to switch cameras.
The system also uses a few structs, to more easily change settings and customize parameters.
This struct holds a few camera settings that are updated when the camera updates. It can be used to easily and quickly customize camera settings for different Movement Modes and Locomotion States.
Falling Animation Parameters
This struct is used in the AnimGraph during the falling state. It holds a few important parameters, and helps to keep the variable count low, so you don’t need to get a float value for each.
Here is the viewport for the Player_CharacterBP. Notice the two cameras, one being FP (First Person) and the other TP (ThirdPerson). Both have spring arms which use the Pawn Control Rotation, but the FP spring arm is attached to the mesh and connected to the Head bone. This makes the FP Camera follow the head at all times, useful for True First Person. Also notice that Use Controller Rotation Yaw in the details panel under Pawn is checked. Since the character rotation is handled in the AnimBP, the capsule can use the control rotation to always face the camera direction. You can also see that a custom component (ALS_Component) has been added to the CharacterBP and can be found in the components tab. Clicking on it gives you access to a lot of important settings in the details panel, such as movement speed, acceleration, jump velocity, etc. This allows you to have multiple characters share the same component and same logic but have different settings, depending on each character’s specific needs.
If you are familiar with the previous version (V1) you will notice that the CharacterBP does not contain as much logic as before. This is because a lot of important logic such as managing character movement and movement modes has been moved to the ALS_Component which can be added to any CharacterBP. This makes it easier to share logic between multiple CharacterBPs, although it is not necessary. All of the logic in the component can be moved back into the CharacterBP if desired. Now, the CharacterBP’s main responsibility is to handle player input, manage the camera, and fire important events in the ALS_Component. The ALS_Component relies on a few events specific to CharacterBPs (they aren’t available in components), so in order to use them they must be fired from the CharacterBP. You can see them in the lower left section of the Event Graph. If you add the ALS_Component to your own CharacterBP, make sure those events fire the corresponding custom events in the component.
Event Begin Play
This is where the UpdateCameraSettings event is bound to the Event Dispatcher located in the ALS_Component. The Rotate Method enum is also set here to be whatever the Third Person Rotate Method is. Anything else you would need to do when this BP starts should / could be done here.
Player Input Graph
This is where all player input is currently handled. You can see in many cases that player input is used to call events in the ALS_Component, such as movement, jumping, changing the locomotion state, and activating / deactivating ragdoll. Of course this is all optional, as any logic located in the ALS_Component could be moved to the CharacterBP.
→ Switch View Mode Event
This event switches the active camera so that players can change from third person to first person. Using a Switch on Enum, it decides whether to activate or deactivate the TP or FP cameras depending on the View Mode enum, which is set right beforehand through the event. It also sets the proper Rotate Method enum. You will also notice that if the view mode changes to first person while in the first locomotion state, it will automatically change the locomotion state to State 2. This is because in locomotion state 2 the character always faces the camera direction, and so is best suited for first person. Otherwise, if the character remained in State 1, the player could look behind and through the character’s head.
→ Update Camera Settings Event
This event is in charge of updating the third person camera’s position and settings when needed. It does this by setting the current values, and then using a Timeline to lerp those values to the target values, which are chosen from the ChooseCameraSettings function. This event is fired by an event dispatcher located in the component, and is assigned to that dispatcher in the Event Begin Play graph. This makes it rather easy to update the camera settings, by simply calling the event dispatcher in the component whenever needed.
Sprint / Walk Check
This graph checks if the character should sprint or walk and then fires events in the component accordingly. By checking every frame, it negates the need to re-press the sprint / walk button if sprinting / walking is interrupted, so that sprinting and walking is more responsive. The DoOnce nodes prevents the component event from firing continually.
Send Movement Input Vectors To ALS Component
The movement input vector is used in the AnimBP, and so it is important that it is set correctly. You will notice that the Get Last Input Vector node is used, but only when it is not equal to 0. When it is, the Axis Values are used instead. This allows the Movement Input Vector to always match the player’s input, even if the Character Movement component is not actively applying movement input.
Lerp Camera Settings
This is the function used in the Update Camera Settings Event, fired from the Timeline. All it does is Lerp the camera settings to their target values by using a Timeline Curve that controls the Alpha.
Choose Camera Settings (pure)
This function contains all of the camera settings for different conditions. It is used in the Update Camera Settings Event to pick the target settings for the camera to lerp to. By using a series of enums, it makes it easy to choose different settings for different conditions, such as movement mode, locomotion state, and sprinting. If you want different camera settings for falling, flying, or anything else, it can all be done here.
Shouldn’t Move (pure)
This function can be found in the Player Input Graph in the Movement Input section. It keeps the player from sending movement input to the ALS_Component if certain animations are playing. More conditions can be added if needed.
Can Player Jump (pure)
This function can also be found in the Player Input Graph, and allows the Jump Input Action to fire the Jump Event only when the CanJump function returns true. In this case, the player can only jump when Shouldn’tMove is false, and the character is in the walking movement mode.
Can Sprint (pure)
This function is used in the Sprint / Walk Check graph, and is used to determine if the player should sprint. You will notice that when the character is in Locomotion State 2, it can only sprint if the movement input is going forward or to the left or right at an angle less than 60 degrees, similar to most first / third person shooters.
Can Walk (pure)
Like the CanSprint function, this is used to determine if the player is able to walk.
Get Camera References
This macro contains all of the needed Camera and Spring Arm References.
Get Movement Mode
This is a simple macro for getting the current Movement Mode from the Character Movement Component.
Get Custom Movement Mode
This macro is similar to the GetMovementMode macro, but returns the current Custom Movement Mode instead. The only difference is that the Character Movement Component returns a Byte for the Custom Movement Mode (because they are not predefined and have no names), so the Byte to Enum node is used to convert the Byte to the custom enum I created called CustomMovementModes. The custom enum just represents the byte value, but has names to keep things better organized.
The component exists to make the sharing of logic between CharacterBPs easier, and to act as a middleman between CharacterBPs and AnimBPs, so that one doesn’t not rely directly on another. This makes it easy to change AnimBPs without having to replace a bunch of references, and helps to speed up the overall workflow. The logic within the component can also be used by either a player character or an AI character.
This event fires important functions when the Component is initialized.
Manage Player Movement Input
This is where Player Movement Input is managed. The Switch on EMovementMode is used to make different types of movement easy to add and customize. You will see these Switches used in similar ways many times throughout the component and AnimBP. Doing this helps to keep the whole system flexible, and easy to expand upon.
→ Normal Movement
This is where normal movement input is applied. This is the most common form of movement input, allowing the player to move in all directions relative to the camera.
→ Ragdoll Movement
This is where movement input is applied during ragdoll. Here, the Axis Values are used to apply torque to the pelvis of the character, allowing the player to flip the character around when falling. This is simply for fun, and serves no real purpose gameplay wise.
Update Movement Settings / Speed
→ Update Movement Speed Event
This is where the Max Walk Speed is changed. The event (fired from the CharacterBP) sets whether the player should be sprinting or walking, and then uses the ChooseMaxWalkSpeed function to determine the new walk speed. It also calls the UpdateCamera event dispatcher, so the camera can update its position while sprinting.
→ Update Movement Settings Event
This is where the Movement Settings are updated. This event should be used whenever you want to update the movement settings on the Character Movement Component.
Switch Locomotion State
This event sets the Locomotion State enum. It also calls the Update Movement Speed Event, but you will notice it does not change whether the character should be sprinting or walking. This is because different locomotion states can have different speed settings.
Set Movement Input Vector
This event sets the Movement Input Vector and makes sure it gets replicated.
Manage Movement Modes
This graph is where many important things related to the character’s movement mode are handled.
→ Do Every Tick
This is where things can be updated every frame, if needed. Again you will notice the use of the Switch on EMovementMode, Here, only the Ragdoll movement mode has logic that needs to be update every frame, but more things can be added here easily.
→ → In Ragdoll
This logic fires every frame when the character is in ragdoll. The Angular Drive Params are updated depending on the velocity of the pelvis. If the pelvis is moving faster, the ragdoll will be stiffer, and if it move slowly, the Ragdoll will be more limp. Here you will also see that a AddForce node is used, but this only runs on no locally controlled ragdolls (other players in a networked game). The force moves the ragdoll to the replicated Ragdoll Location vector. This is to make sure the ragdoll ends up in the correct location when networking.
→ Switch Movement Mode Event
This event sets the character Movement Mode and makes sure it executes on the server as well. You can call this event from a CharacterBP to easily change the movement mode whenever needed.
→ On Movement Mode Change Event
Whenever the Movement Mode is changed, this event is executed (It gets called from the CharacterBP). Notice how the UpdateCamera dispatcher gets called as well.
→ Movement Mode Events
These Collapsed Graphs hold events important to specific movement modes.
→ → Ragdoll Events
Here are the ragdoll events for the character. These events are responsible for making the character simulate physics, and then blending back out again.
→ → Jump / Landing Events
The JumpEvent gets called from the CharacterBP, and simply causes the character to Jump. The LandEvent executes whenever the character lands, and is also fired from the CharacterBP. When the character lands, the Braking Deceleration increases dramatically for a short period of time, causing the character to stop moving more quickly. This allows for more accurate landings.
→ Update Custom Movement Mode Event
This event is called from the CharacterBP and executes whenever the character is currently in a custom movement mode. It is similar to the tick events.
→ → Update Ragdoll
This is where the ragdoll’s position is calculated and sent to the server. Only the locally controlled player will calculate its ragdoll position. The Actor Location during ragdoll is also set here.
Set Mesh Rotation (Server Only)
This is where the mesh gets rotated, but only on the server. For some reason, AnimBP’s (which handle character (mesh) rotation in this system) dont evaluate the same way on servers, and thus don’t rotate the character properly. The Mesh Rotation is still set from the AnimBP, however the mesh itself is rotated here, which mitigates the issue of the mesh not rotating correctly on servers.
This function is called upon the component’s initialization and sets all the important references that will be used later throughout the component.
Set Default Settings
This function is also called upon initialization, and sets the default Movement Settings for the character. It also calls the Update Movement Speed Event to make sure the movement speeds are correct.
Set Player Movement Axis Values
This is where the Player Movement Axis Values are set. They are multiplied by a multiplier, which can be used if needed (not used yet).
On Movement Mode Change
This function is called when the movement mode changes. It gets the new and previous movement modes, so that it can use them to call certain functions or events. This is useful for making sure certain things happen whenever depending on the previous or new movement mode. Here, the UnRagdoll and ToRagdoll events are fired accordingly.
Calculate Actor Location In Ragdoll
This function calculates the actor’s location while the character is ragdolling. For most part, it simply uses the Ragdoll Location vector, but it offsets the Z position when near the floor by using a trace. This makes sure the capsule stays on the ground when the ground is in reach, so the capsule doesn’t fall from the pelvis location when blending out.
Choose Max Walk Speed (pure)
This function is used in the UpdateMovementSpeedEvent and selects the appropriate speed based on the locomotion state, and whether or not the character is sprinting or walking.
Choose Get Up Montage (pure)
This function chooses the get up montage. It looks at the rotation of the pelvis joint and determines if the character is facing up or down, and selects the appropriate montage to play.
Get Forward / Right Vector
This macro is used in the Normal Movement Input graph. It just gets the forward and right vector of the control rotation, so movement stays relative to the camera.
This macro is used whenever an event should be fired only from the server.
Is Locally Controlled
Like the HasAuthority macro, this is used when certain things should only be done by either locally or nonlocally controlled players.
The Event Graph is responsible for setting important variables that will be later used in the Anim Graph, and is also responsible for handling character (mesh) rotation.
This graph will keep the Update Animation event from executing anything if the Pawn Owner is not valid, or Delta Time X equals 0.
Set Important Variables
This is where many important variables needed in the Event Graph and AnimGraph are set every frame. Notice that I use a Switch on EMovementMode to only set certain variables if certain movement modes are active. This keeps the BP from setting variables that aren’t needed in some movement modes, and also allows you to set a variable in different ways depending on the movement mode.
→ Do Every Frame
This graph executes every frame regardless of the Movement Mode. These variables are essential to many parts of the AnimGraph, and so they are set all the time. It also calls important functions that are needed every frame.
→ Update While On Ground
This graph executes only when the player is on the ground.
→ Update While In Air
This graph executes only when the player is in the air in the Falling Movement Mode.
→ Update While In Ragdoll
This graph executes when the player is in the Custom Ragdoll Movement Mode, and is responsible for changing the rate of the flail animation based on the ragdoll’s velocity. The faster the ragdoll falls, the faster the animation will play.
Manage Character Rotation
This graph is the responsible for determining how the character should rotate at any given time. Like the Set Important Variables graph, it uses a Switch on EMovementMode to better manage how the character should rotate in different movement modes. The branch cuts off the logic flow and prevents the character from calculating any new rotation value if Shouldn’t Rotate returns true. Anything related to character rotation can be done here, and the graph can be expanded to fit your needs.
→ On Ground
This graph is responsible for calculating the characters rotation while on the ground. The CustomRotation macros contain custom rotation logic, and are used to keep things organized. Each macro makes the character rotate in a different way.
→ → Turn In Place Graph
→ → Rotate In Place Graph
When the character is on the ground, not moving, and the Rotate Method enum is set to RotateInPlace, this graph is executed. Here, different paramaters are fed into the Rotate In Place function depending on the locomotion state. It also fires the Stop Turn In Place event if turning in place is true.
→ In Air
This graph controls the character rotation when the character is falling. It uses a Switch on Locomotion State similar to the Grounded graph.
→ In Ragdoll
When the character is in ragdoll, this graph updates the Character Rotation so that the character will face the correct direction when getting up. The pelvis bone rotation is used to determine that the rotation should be.
→ Set Mesh Rotation
This is where the mesh rotation is set. It uses the Character Rotation rotator to continuously set the mesh rotation every frame. It also sends the rotation to the Component so it can be used there if needed (for servers). The 90 degrees subtracted is needed so the character will face forward.
Anim Notify Events
All of the Anim-Notify events are located in this graph. Keep in mind that most of these events are fired from state machine transitions, instead of animations.
→ Set Idle Entry State
The Idle Entry State enum is used to determine which idle state to enter in the Idle State Machine. If an animation (get up animation for example) ends in a specific idle pose, but the the character is in a different stance, than this enum can be used to transition into the correct idle pose first and then to whatever other pose it should be in.
→ Entered / Left State
These events are used to determine which if certain states are active or not. If the Idle state or Grounded state is left, than the character will stop turning or rotating in place.
This anim notify event fires when the Stopping state is blended into, and is used to pick a stopping animation.
Whenever the character enters the Falling state, this event fires.
Similar to the Falling Anim Notify state, this event fires when the character enters the Land state. It sets the landing animation, and also plays an additive land animation. The additive land animation is used to add compression to the character when it lands and continues to move.
This graph contains a few custom events.
→ Turn In Place Events
→ Rotate In Place Events
The Stop Rotating In Place event stops the character from using any Rotating in Place animation. It resets the Rotate in Place Time (used in Rotate In Place function), and also sets the Rotation Animation Play Rate to 0 to stop the feet from moving as it blends out.
This function gets a bunch of important variables from the pawn, and sets them every frame. If the CharacterBP has the ALS_Component, it get those variables as well.
This function is used heavily throughout the Manage Character Rotation graph. It sets the Character Rotation rotator to whatever is fed into the Target Rotation input on the function. It sets the Target Rotation rotator first (not used yet, but useful) and then interpolates the Character Rotation rotator to the Target Rotation if Interp Rotation is true. If not, it won’t do any interpolation.
This function is responsible for setting the Aim Offset value, to be used in the aim offset in the Animgraph. It sets it in different ways depending on the locomotion state. In State 1, the character will look in the direction of the movement input, while in State 2 and 3, it will behave like a traditional aim offset, with the player always looking in the camera direction.
This function rotates the character if the angle between the character and camera passes a certain threshold (Rotation Degree Limit). It also sets the Rotation Animation Play Rate float to be used in the AnimGraph to scale the rotation animation’s play rate to match the speed of the rotation. The Min and Max Rotation Rate inputs are used so rotation starts off slowly, and then increases in speed as time (Rotate In Place Time) increases. This is mainly for aesthetic purposes, so the rotation is not visually jarring.
This function simply sets certain Anim Curves every frame. These animation curves are located in certain locomotion animations, and are used for the Stopping animations.
This function is called whenever the character enters the Falling State in the Animgraph. Its job is to predict the path of the character through the air, and then calculate the time it will take the character to reach the landing spot. This time is used to sync up the falling / jumping animations to the time of the fall so that the character appears to know when he is about to land.
This function simply sets references to important components needed throughout the AnimBP.
Similar to the previous function, this one sets a reference to the ALS_Component, but only if it is valid (added to the character).
This function controls the branch in the Manage Character Rotation graph that determines whether a new rotation should be calculated. If either of these montages are active, than a new Character Rotation will not be calculated, and the character will not rotate. More montages / animations can be added easily, by simply adding a pin to the OR node, or by adding more logic / conditions.
This function selects a stopping blendspace.
This function sets the Falling Anim Params, which is used in the Falling State of the Anim Graph. The Start Time, Apex Time, and End Time are used to sync the animation. Notice that if the character is falling down (Fall Speed > 0 = false) then the Start Time and Apex Time is the same.
This function simply choose the landing animation. Since there is only one landing animation, only one can be selected. More can be added if desired, and can be chosen by different conditions, such as the characters fall speed.
Custom Rotation Graphs
The custom rotation graphs are used in the grounded section of the Manage Character Rotation graph. They are essentially custom rotation profiles, and are put into macros so they can be easily added anywhere else in the rotation graph. Their sole purpose is to customize how the character rotates during locomotion or other movement.
Custom Rotation_1 is essentially just standard (or traditional) third person movement. It makes the character rotate in the direction that the character is moving (Last Velocity Rotation). It also sets the Cardinal Direction to north, and the Movement Direction to forwards. The Rotation Offset Float is also set, but not used here. It is set so that blending between different custom rotation graphs is stays smooth. The rotation rate (Interp Speed) uses a Map Range Clamped node, so that the rotation rate increases as speed increases.
Custom Rotation_2 acts as a hybrid between strafing and normal movement. In this mode, the character will always face the camera direction, and will run backwards if moving toward the camera. The only difference between this mode and traditional strafing, is that the character can rotate 90 degrees to the left or right, so that locomotion appears natural. The Cardinal Direction and Movement Direction enums are set by getting the Yaw between the Last Velocity Rotation and the Actor Rotation, and seeing if it is in a certain range. The Cardinal Direction controls how much is added / subtracted to the Rotation Offset (which is the delta between the velocity and actor rotation), and the Rotation Offset is added / subtracted to the Actor Rotation to produce the final Target Rotation. If the Cardinal Direction is South (character moving toward camera), then 180 degrees will be added / subtracted to the Rotation Offset, and the character will continue to face forwards but run backwards.
Custom Rotation_ 3 behaves similarly to traditional strafing (character can walk side to side, and forwards to backwards) but an offset is still utilized in order to negate the need for 8 directional strafing anims. With this mode, the characters rotation can be offset 45 degrees with each cardinal rotation, so that a side strafing animation can also cover the 45 / 135 degree angles.
This macro is used extensively in Custom Rotation Graphs 2 and 3. It essentially checks to see if a value is in a specified range, but has two different ranges depending on if the boolean is true or not. This allows for some extra ‘give’ while changing cardinal directions. For example, in CustomRotation_2, the cardinal direction will switch to South when the angle between the Last Velocity Rotation and the Character Rotation is greater than 100 degrees, but wont switch back to North until it becomes less than 80. This prevents the cardinal direction from switching rapidly if the angle is around 90 (moving to the sides).
This macro returns the Anim Instance, to be used later. It just makes getting the Anim Instance easier.
The Anim Graph is responsible for determining which animations should be playing at any given time. It contains all of the blendspaces, state machines, and transition logic needed to get the character to animate properly. This Anim Graph uses hierarchical state machines (state machines within state machines) in order to keep transition logic simple and flexible. There are really limitless ways to organize an Anim Graph, and each game might require a slightly different setup. It all depends on your available animations, and how you want them to work together.
This Blend Poses node uses the Custom Movement Mode enum, and will blend the character into the InRagdoll State Machine if the Custom Movement Mode is in Ragdoll. It is done last in the chain, so that the final pose is not affected by aim offsets, or anything else that comes before it.
In Ragdoll (State Machine)
This is the InRagdoll State Machine. It consists of two states, and will remain in the InRagdoll state while the character is ragdolling. If the Enum no longer equals Radoll, it will immediately transition into the BlendOut state, so the character can blend out of the Ragdoll pose.
→ In Ragdoll (state)
These animations will play when the character is Ragdolling. The flailing anim is controlled by the Flail Rate float (set while character is ragdolling in the event graph). If the player is sprinting and movement input is being applied, then the character will blend into a curl pose.
→ Blend Out (state)
The Blend Out state uses a Pose Snapshot, in order to blend out of the last pose the character was in while ragdolling. The Pose Snapshot is set in the component in the Ragdoll Events.
This is where the Aim Offset is applied. It is applied to the Default Locomotion Cached Pose if Enable Aim Offsets is true.
Default Locomotion Cache
This is where the Default Locomotion State Machine is cached, so that it can be later used in other parts of the Anim Graph.
Default Locomotion State Machine
This is the Default Locomotion State Machine. Right now it is very basic, and only has a few states, which are transitioned in and out of based on the Current and Previous Movement Mode. The Movement Mode Conduit is used to keep transition logic organized. More states for different movement modes like Swimming and Flying can be easily added here. Some transitions (conduit → Land / falling) fire Anim Notify Events. (click on a transition and find the notifications panel).
→ Grounded (state)
Inside of the Grounded state you will find another State Machine. This hierarchical design keeps transition logic simple, but also allows for complex setups. Having a State Machine Within another State Machine makes it easy to transition in and out of by a single transition and condition.
→ → Grounded Locomotion State Machine
This is the Grounded Locomotion State Machine. This is what is active whenever the player is on the ground. It is simple at the moment, but more states and transitions can be easily added here (like starting, pivots, etc).
→ → → Not Moving (state)
Inside the Not Moving state you will find Rotate In Place anims, and yet another State Machine. The additive animation provides secondary motion to the Idle poses, so that animators can quickly create new poses without needing a full cycling idle animation.
→ → → → Idle State Machine
The Idle State Machine contains all of the Idle Poses, and necessary transitions. The Entry state is empty, and serves as a gateway so that any number of poses can be entered by using the Idle Entry enum.
→ → → Moving (state)
All of the movement animations for locomotion can be found within the Moving state. Keeping all movement animations inside a single state regardless of Locomotion State keeps the graph simple. Different Blendspaces are selected by different conditions. Notice that all locomotion blendspaces share a ‘Locomotion’ sync group. This keeps the foot cycle in sync when blending from one blendspace to another.
→ → → Stopping (state)
Inside the Stopping state you will find a Blendspace Player node, set to use whatever the Stopping Animation variable is set to be. The Additive provides secondary motion just like with the idle poses.
→ Falling (state)
In the falling state, the selected Falling Animation is played, and is synced up to the Predicted Air Time or the Fall Speed, based on wether Use Predicted Air Time is true or not.
→ Land (state)
The Land state is activated only when the current Movement Mode is Walking and the Previous Movement Mode was falling. It will play the selected Landing Animation, and blend out if it finishes or if movement input is applied.
This system uses a unique method for playing turn in place animations. Traditionally, turn in place animations would use root motion to rotate the character, however, because mesh rotation has been separated from actor rotation (root motion affects actor rotation), a traditional root motion approach would not work well. Instead, the system uses a custom anim notify state to fire a function in the AnimBP that rotates the mesh over time using a curve asset.
Turn In Place Graph
When the character is grounded and not moving, and the Rotate Method enum is set to Turn In Place, this graph will execute. If the character is rotating in place, it will call the Stop Rotating In Place custom event, and then check to see if the player is turning in place. If it is not, then it will call the Turn In Place Check function. The Switch on Locomotion State allows for the same function to be called but with different inputs, so that turning in place can be customized for each locomotion state.
Turn In Place Check Function
This function checks to see if the angle between the Actor (camera) Rotation and the Character Rotation is above a certain threshold, and if so, starts the Turn In Place Delay Count. Once that delay (seconds) becomes greater than a certain limit, it will fire the Play Turn In Place Animation custom event. The function supports two different angle thresholds, so that two different turn animations can be selected (90 degrees, or 180 degrees). The Timer Delay A and B inputs are mapped to the Timer Angle A and B inputs, so that different camera angles cause different delay limits. For example, if the camera was looking 90 degrees over the character’s shoulder, the delay limit could be set to 2 seconds, and if the camera angle increases to 180 degrees, the limit could drop to .1 seconds. This allows the turn to happen quicker the further you look over the character’s shoulder.
Turn In Place Custom Events
This is where the Turn In Place Custom Events are located. The Play Turn In Place Animation event is fired from the Turn In Place Check function, and its job is to select a turn in place curve, reset a bunch of variables used in the Turn In Place function, and then play a turn in place animation (selected from the Turn In Place Check function inputs)
Can Turn In Place (pure)
This function checks whether the character can rotate in place. It will only allow the turn in place animation to play if the character is grounded and in the Idle state (set from the Anim Notifies)
Choose Turn In Place Curve (pure)
This function chooses the appropriate curve asset to be used depending on which Turn In Place anim is selected.
Turn In Place Curves
These curve assets are used to rotate the mesh during the Turn In Place function. They should match the rotation of the root bone (if the animation had root motion). In this case, the curve goes from 0 to 90, so the player will rotate right 90 degrees.
Turn In Place Animation
This is a turn in place animation. It doesn’t have any root motion, as it was taken out during the animation process (curve asset should match what the root bone rotation should have been). The anim curve is just a custom curve exported from maya, and is not used, although it can aid in the creation of a curve asset if needed. You will also see that an anim notify state (Turn In Place Anim Notify State) has been added to the animation and stretched to fit the entire timeline. Whenever the animation is playing, it will call this anim notify state.
Turn In Place Anim Notify State
The anim Notify State is called from the turn animations, and fires events and functions in the AnimBP. It casts directly to a specific animbp, so in order to use turning in place with another animbp, these references must be updated or a new anim notify state should be created.
When the Notify begins, it will fire the Start Turn In Place event.
As the animation plays, it will continue to fire the Received Notify Tick event, which will continuously call the Turn In Place function from the animbp.
When the anim notify state ends, this event execute, firing the Stop Turn In Place Event.
Turn In Place Function
This is the function (called from the anim notify state) that actually rotates the character. It counts up a Turn In Place Time float, and uses that time to get the In Time of the selected Curve. It subtracts the Previous Curve Value from the current curve value, setting the Curve Value float which is added to the current Character Rotation rotator. This final value is used as the new Target Rotation.
Stopping can be a very tricky part of locomotion systems, especially if you are aiming for responsive movement. Many games utilize root motion stopping animations, but they take away from player control, and can lead to frustrating situations, such as the character moving too far forward after the player stops applying movement input. In order to maintain fluid control, I’ve developed a system that minimizes foot sliding when transitioning from moving to idle. Although it is not 100% naturalistic, it can greatly add to the visual quality of the movement and animation. The system uses a set of transition animations in a blendspace, controlled by anim curves on the locomotion animations.
The Stop blendspaces are used to blend back from moving to idle. They consist of various transition animations, that are made to reduce foot sliding. The transitions are animated from poses that closely match where the feet would be during the extremes of the locomotion cycle, so that the feet don’t move far when blending to them. They are also animated in a consistent way so they blend together nicely on blendspaces (each transition starts with the same foot). They are then added to a blendspace, with a horizontal Foot Direction axis, and a vertical Foot Position axis. The Foot Direction goes from 0 to 90 and represents the direction of the character (similar to locomotion). The Foot Position represents the feet position in the locomotion cycle (-1 = left foot forward, +1 = Right foot forward).
These anim curves can be found on the locomotion animations. They define which position of the Stopping blendspace to blend into when stopping. The Foot Position curve cycles between -1 and +1, as it represents the foot cycle (-1 = left foot forward, +1 = Right foot forward). The Foot Position Direction curve should be a single value for the entire curve, and represent which direction (angle) the player is walking. In this case it is -90 because this is from the Walk FL (left) animation. The stopping animations should also have these curves on them, but should just be constant values, representing their location on the graph (so the curve value does not change the graph position when in the blendspace).