Help with Tomb Raider jump mechanic

Hi i’m a making a game inspired by tomb raider, i want run and sprint in my game but the jump distance needs to remain the exact same despite the different movement speeds on foot. Just like how its done in rise and shadow of the tomb raider.
Can anyone help me achieve this? If it’s useful info, i am using AGLS by Jakub w for this project, which is like ALS, the movement speed is done in a movement model table.

Hi welcome to the community, I am not sure what AGLS (seems does more than movement) does but the thing you want interms of movement is quite simple.

Assuming that you are using blueprints, on the moment of jump you can clamp speeds to a certain value and let the jump function do the rest.

OnJumpInputPressed()->DoJump()

DoJump()

HorizontalVel = (GetVelocity().X, GetVelocity().Y, 0)

JumpZVelocity = Something like 600 to do constant height.
MaxJumpHorizontalSpeed = Something like 800 this will be the max speed. Standing still is zero 0 and while moving whatever speed the character is will be horizontally max 800

 // Get current velocity
Speed2D = Length(HorizontalVel)

 // Lets clamp values of our speed to a constant value.
ClampedSpeed = Clamp(Speed2D, 0, MaxJumpHorizontalSpeed)

// Lets create a vector to desired jump
// Simply normalize velocity and multiply with clamped to maintain a constant max.
// then we add a z  velocity for jump height.
LaunchVector =Normalize(HorizontalVel) * ClampedSpeed + (0,0,JumpZVelocity)

// Make jumping.
LaunchCharacter(LaunchVector, true, true)

This will always give you arcade like (Tomb Raider like) constant jumps, no matter what characters incoming velocity is. However if you want a jump that is also constant while character standing still let me know. Another options is to properly write movement jump() in character movement component, or create a custom jump but that requires C++ movement development.

PS : Checked the github files (if its correct) there should be also an event as OnJumped in your ALSBaseCharacter so on that event basically you can still override speeds without C++ and without interfering what AGLS does simply on blueprints like below.

OnJumpedEvent 

CurrentVelocity = GetVelocity()
ClampedVelocity->BreakVector->Clamp(CurrentVelocity.X, 0, 800)) // clamp all xyz floats ->MakeVector
CharacterMovementComponent -> SetVelocity(ClampedVelocity)

Hi thanks for helping! Unfortunately I’m really not great at programming, and I’m struggling to understand a lot of this lol. Sorry if this is annoying, but if you have time at some point it would be helpful to see this set up in actual blueprint.

For now I tried something that might be similar to what you suggested. I’ve shared an image below. It kind of works how I want. When jumping from a run you get a small boost in the air, and when jumping from a sprint you get slightly slowed down, both seem to match the same jump distance despite the different speeds. (My run speed is 400 and sprint is 520 for now)

The only issue I’m seeing is that if you do a sprint jump, the launch works at first, but then you start picking up speed again mid air if you’re still holding sprint. I don’t want that, because it means the jump distance is increasing again. I messed around with a few things and noticed that if I set air control to 0, the problem goes away, but I’d like to keep air control since it helps the player adjust in the air slightly and grab a ledge easier etc.

Do you know a way to keep Air Control but stop sprint from affecting speed while in the air? Or if everything I’m doing is wrong do let me know, it’s the only thing I could come up with.

I understand, no worries at all that’s exactly what community forums are for and yes you’re seeing the correct behavior. Nothing is wrong with your setup , it’s just how Air Control works in Unreal.

Why it happens?

When Air Control is enabled, the CharacterMovementComponent continues to applymovement input acceleration while falling.

So if you’re still holding your sprint + forward input in the air, the movement component keeps accelerating you toward sprint speed again which increases jump distance. Simply disabling it solves the problem but we don’t want that entirely

If you don’t want this, in bluprints where you make MovementInput, simply create a branch with bool bIsFalling, and during the falling movement we want to neglect the forward value. (W Key or whatever Input Value)

InputAxis MoveForward()→ Branch (CharacterMovement → IsFalling)

// So even player presses input we ignore it and nothing is added to movement
True:   (Input.X = 0 , Input .Y = Connected) 

False:  Use normal setup.

Something like this with your inputs, you just ignore Forward , lateral movement we keep.

Mine looks a bit different, and i cant find the Do Move that you have.

It’s a custom event he made. This may entice players to move sideways to be able to jump further. I think there might be a more elegant solution to this like movement in air is pushed towards Character Forward Vector and your left/right just controls rotating your forward direction. This solution would mean you never induce air control.

That’s correct it’s a custom pawn and DoMove() don’t exist in yours, seems this created some confusion.

I open a template and here how it should be overall.

Regarding @tyconner’s point about sideways air movement enabling players to gain extra distance that is true. In movement heavy games like Quake, this is actually an intentional mechanic (strafe-jumping) and requires player mastery. So whether it’s a “problem” depends on the intended movement design.

In this case, as I understand it, @Mapesy wants lateral air adjustment for ledge grabbing and fine control, but does not want sprint acceleration affecting jump distance.

By ignoring only the forward movement input while falling and allowing right/left input

  • Prevent sprint from rebuilding forward speed mid-air
  • Keep lateral air control for adjustments
  • Preserve consistent jump distance

If lateral air movement is not desired at all, Air Control can simply be set to zero but in this case we’re selectively filtering forward input to keep the intended feel and this physics movement for sure can be done as a custom jump function on movement physics but this is a workaround simply bypasses component’s jump logic. Rather than rotating character we can clamp sideway movement speed on custom function never exceeding jump velocity simply is the right way of doing it which can be overkill for this topic atm.

This fixed that problem! I did notice an issue with this though. In AGLS, grabbing a ledge requires you to be holding W, otherwise you’ll fall past it. I think it needs forward movement, and it seems like we are preventing that so in some situations its causing problems.

Is there a way to make it so you can have forward movement while holding sprint in the air, but no more than the run speed so it still stays the same? If so i think that might be a fix.

:slight_smile: Hack incoming, make your forward not zero but 0.01, something small :slight_smile:

Joke aside that is super ok for a prototype and test before making it better. Just keep forward very small value in air and this will inject movement and forward is not blocked but it would be less than noticable.

Let me know if it works, and if not we can even try something else.

where can i change this value?

try this.

So when grounded normal we have both right and forward vectors , they are added and works normally. Movement component has its internals to process that.

When bFalling meaning fundamentally jumping, I get right movement fully but add this time a very small (clamped) forward vector. It is there so your button should work but the jump length should be effected not noticable at all.

Let us know.

Thanks, I think that works! A few more things, this time back to air control. When jumping while sprinting, you can still gain speed by moving left and right. I guess this is needed this so you can still actually move around in the air, but is there anything we can do to limit it, like capping it at run speed or something so its the same?

Also, when jumping, it seems like jumping with just the W key is actually a shorter jump distance than jumping with W and A or D, or even just A or D on their own. I’m guessing it’s a similar issue where moving sideways can still pick up speed, but forward movement has basically none?

1 Like

My pleasure, great if it works. Ofcourse you can do it, If you just search in CharacterMovementComponent words like air, speed, velocity, you will see many things that you can play around at your disposal exposed by Epic.

For your question you can just clamp velocity. Since we kinda know what you want and what is going on with your movements and inputs atm what I would like to mention couple of things especially on design aspects.

  • Falling doesn’t necessary means that player is jumping, generally jumping is a request from player and jump sometimes can be started or not. Basically any movement on tick and its nature depends on it. So falling can occur in many situations it can effect your gameplay. In your addon or in your default pawn class there should be some events that you can use. I recommend searching them.
  • Understand how ledge grabbing works on your addon, try change your logic according to that in movement or your grabbing logic. This small input dependency was just a guessing from my side and it worked by luck.
  • This things generally prototype and you can do many things with already existing functions however granular tweaks and really robust movement will require C++ and medium to advanced level however if you are interested I was watching some videos recently just to keep my brain muscles working. Basically its physics kinematic custom movements so in future if you want a custom jump that is robust that is the way to go.

Below is somewhat another proper approach to just clamp velocity on jump so its bypassed. Carried a bool over jump and landed, there is also bWantsToJump somewhere. This also should work the same as you wish, since we clamped velocity XY it should give you air control but not a bigger jump. That should also solve jump distance problem coming from input interference. As a side note I was checking good old tomb raiders on net and seems they also use custom defined arcs and curves, which is something cannot be done by bp


So if above is true which I remember absolutely nothing about which is nice thing and requires branching player’s jump request with possible different jumps functions.

Happy developing.

1 Like

Thanks for your help today, I’ve learned a few things. I may have some more questions tomorrow if another problem pops up, hope you don’t mind :sweat_smile: .

I’ll check out that video sometime, I need to improve on this side of games dev. Level design is my focus, but it’s still important for me to be good at this stuff as well.

1 Like