Creating a mantle system similar to that of Destiny 2 using animation motion warping.
This article expains how the mantle system was implemented using a mix of collision tests, traces and UE5’s motion warping plugin.
One of the main improvements that Destiny 2 made over the original game was adding a mantling system. This system works by automatically climbing on to ledges and platforms, greatly improving the game feel when trying to do platforming puzzles (a main section of some levels in the game). Many games have a dedicated button to mantle onto ledges, however Destiny 2 uses a simpler method of activation for the mantling system. The criteria to activate the mantling system are the following:
Once a mantle is activated, depending on the vertical distance to the ledge, the player will perform either a short hop animation or a proper mantling animation in which the players left hand ungrips the weapon and moves to simulate placing their hand on the ledge.
In my project, the mantling system is mainly done in blueprints. On the player characters Event BeginPlay
, the MantleCheck
Event is bound to the On Component Hit
delegate of the players capsule component:
Once a collision is detected, the mantle check event first checks if the other actor in the collision is a Static Mesh Actor
and then performs condition checks to see if the requirements for mantling are met. The main three checks done at this stage prevent further mantle operations such as line trace and collision checks from being carried out on a collision with a static actor in which the player isnt allowed to mantle in the first place.
The IsMantling bool prevents a mantle from starting if the player is currently mantling. The CanAttemptMantle function is a custom function in C++ that comes from the custom CharacterMovementComponent which returns true if the player is airborne and currently pressing the move forward input key. Finally RecentlyJumped
is a bool that is false for the first 0.5 seconds after a player jumps. Since the jump key event is only registered on the player client, in order for the RecentlyJumped
variable to be the same on the server and client, a reliable RPC event is used to set the value of RecentlyJumped
from the client on the server player character as well:
Once the initial conditions have passed, the main mantle algorithm performs line traces from the facing the forward direction of the player to check if mantling can be performed. A total of 5 line traces are performed (this number can be changed for more or less precision at the cost of performance). To begin, an initial line trace is performed from the top of the capsule forward. If this trace hits something it means that the mantle cannot be performed and the mantle check exits out early without the need to perform more traces:
Once once of the line traces for the mantle are confirmed to be valid, we check if the player is facing the correct direction and set the player to be uncrouched to ensure that the following clearance check isnt affected by the player capsule being smaller because of crouching.
Then a clearance check is ran on the expected mantle location. If there is not enough space for the player character, the mantle will not trigger:
The final step before handling the mantle movement and animations is to set the final mantle position variable and to decide wether a short or a tall mantle animation is needed:
The main movement of the mantle is performed using Unreal Engine 5’s motion warping plugin. This plugin allows syncing animation root motion to end up in specific positions and is extremely usful for a task such as this one. For each of the mantle types (short and tall), a third person and first person character animation is needed. The motion warping is driven by the third person animation, as this animation will paly on both the client and the server, while the first person animation is cosmetic and thus client only (since the client is the only one that can see first person animations)
The motion warping is divided into two sections inside of the animation montage, one for the vertical movement the character does to get to the ledge and another for the horizontal movement to step onto the ledge:
With the motion warp set up on the animation montage, the next step is to set the warp targets for both the vertical and horizontal movement just before playing the animation:
The final step is playing the correct mantle animations. If a tall mantle is needed a final check is done to see if the player is looking in the general direction of the ledge. Then the movement mode of the player is set to Flying
while the vertical motion warping is playing and the variable IsMantling
is set to true until the animation finishes playing. If the player is locally controlled, the first person animation also plays: