Character Jumping in Unreal Engine

MarkBlog

Jumping in video games is ubiquitous. From platformers in both 2D and 3D, to avoiding hits in first-person shooters, having a character that can jump is something many of us take for granted. During the development of Walkies, our dogs movement (and in particular, jumping!) has gone through a number of iterations and improvements.

Character Movement Component

Walkies is developed using Unreal Engine, so we start with the Character Movement Component.

Once we have configured our Input controls, sorted the bindings (in our Player Controller) and passed them through to the controlled character, we can simply call the Jump node on the character. This is all pretty standard stuff, but we’re just getting started!

Wind Up Frames

When you use this approach with, for example, the Unreal manequin, jump causes an upwards increase in Z-Velocity and the Manequin enters the in-air animation state. But with this approach there is no compression of the legs.
The first thing we do is have a few “wind-up” frames before leaving the ground. Now when the Jump input is passed through, we start the animation. Within Unreal, we add a simple notify for when the dog should leave the ground and call a custom function “OnAnimStartJump.”

Once this hits, we can then call the actual Jump node and the Dog will be launched into the air. Of course, this separation between the button press, animation and leaving the ground can lead to the first feeling of unresponsiveness with jumping.
To fix this, we simply increase the playback rate of the jump animation until it both feels responsive and still shows sufficient wind-up animation frames to sell the effect.

Fuzzy Landing

Any 3D games that have elements of platforming have an inherent issue with precisely knowing where the character is, in relation to the floor. Sometimes you can be just on the ground, but all the other systems have not yet stated you have landed, to be able to jump… that when you press jump, nothing happens.

The best example and solution can be seen in this Nintendo Ask the Developer session, about Kirby and the Forgotten Land.

In Kirby, the developers called it “Fuzzy Landing” and it clearly explains the issue stated above – when you think the character is just on the ground, but they aren’t. We implemented a distance check with the ground and if you were within a tolerance of the ground, then we now call the Unreal node Launch Character.

The “Ledge Falling” problem

When leaping from surface to surface in any platformer, timing can be critical. There are times where it still looks like your character is on a ledge and able to jump, but when you press the button, they simply slide off the surface.

Most characters in video games are represented by a Capsule that surrounds the actual player geometry. This capsule is what is moved around in the world, with the mesh updating the animations based on the velocity of the capsule. In the above image, you can see the capsule around the front portion of the Dog and the hind paws are just leaving the rocks surface. However because the capsule has started to fall, then the dog enters the appropriate animation state.
(The above is true for “In Place” animations, which are typically simpler to implement, especially when it comes to network/online games! Root motion animations work differently and there are plenty of resources out there to understand the differences, find out which is best for your needs. Anyway, back to jumping…)

When your Character capsule approaches the edge of a ledge, it can begin falling off said ledge. At which point it enters the “falling” state and your character can no longer jump. In Walkies, our dogs hind legs were often still on the surface of the ledge and this makes players feel like they ought to still be able to jump.

To get around this, we added a simple Timer and a jump override. If you press Jump before the Timer, we call Launch Character. If outside, the Timer completes and you’re still falling. This also allows us to add an accessibility option to adjust the allowance time between falling and jumping.
In the above picture, the Launch Character has applied the Z velocity even though we had technically left the rocks surface. To a player, this feels much more intuitive, responsive and fun!

Scrambling/Climbing

When jumping around platforms or simply trying to reach a high point, there are times when a helping hand can make that experience all the more rewarding and intuitive. Often times when players were trying to jump up some ledges, their direction or speed was just not quite what was needed and the dog would bounce off the target surface.

To make traversal more fluid, we added a Scramble mechanic.

The first step is to make two simple projections both ahead of the dog and down from the shoulders. We only trigger this check when the dog is jumping and if a valid surface is detected between the two projections, then we can initiate a scramble.

We use a custom modified version of the Move Component To node, with our version supporting a few elements, most notable is how we actually move the Component. The default implementation could cause our Dog to often get stuck within other geometry as the Move node isn’t taking collisions into account. To get arround this we make use of FindTeleportSpot, which will try to correct the location against collision geometry of other surfaces.

Real Shadow and Ground Spot

Unreal Engine gives us some fantastic lighting and shadowing right out-of-the box. However, we still need some way of being able to know where the ground is, right beneath our character.

After experimenting with various ways of showing some ground location on the floor, it wasn’t until after playing the fantastic It Takes Two, did I spot their solution: A simple shadow circle.

This circle fades out the closer you get to the ground and becomes more and more opaque, the higher you are above a surface. This way, you always have a target point that you know you can land on!

Here you can see the “Real” shadow of the dog (bottom right) but also the ground target shadow (in the red circle). This moves directly below the Dog and fades in/out to always give you a point to aim at.

Closing

These are a few of the areas that we have been utilising to solve and improve the jumping in Walkies.

In all of our player centric code, nothing is “hard coded,” everything has variables and adjustable values. We (as developers playing and testing every day) very often become accustomed to how the game feels, what the current jump values are and the current level of responsiveness… so when player feedback challenges our norms, we can rapidly re-evaluate how the Dog currently handles, iterate a few numbers and rapidly have improved input, movement and responsiveness.

Hopefully some or all of the areas above will help others looking into 3D platforming, or simply wanting to improve how jumping feels in your games!