How do I make a third person character keep their forward speed while turning?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Rilic

How would I make a third person character that keeps their speed while turning, as opposed to the usual sliding collider method? It would be similar to how NieR:Automata does it, if anyone’s played that.

My current idea on how to emulate this is to steer the player towards where the input is driving them, using turning speed variables for the interpolation of the rotation, while keeping a constant forward-moving speed. However, I don’t really have much vector math knowledge to do this in GDScript.

Can anyone help with this?

This is very hard for me :wink:

ViolaRose | 2021-07-07 06:28

how do you handle turning and acceleration/deceleration?

klaas | 2021-07-06 15:21

Thanks for replying,

I was following this tutorial initially.

It’s a simple movement setup with linearly interpolated velocity, so the character just slides around based on the input direction and position of the camera.

I’ve seen a lot of third person games keep the movement speed of the character up as they’re turning, and NieR does it in a somewhat clever way: the turning is instant if there are small adjustments in direction (think moving the stick slightly to the left on a controller), but it takes a little bit of time to turn around if the adjustment is big enough (think making a circle with the stick), as if it’s steering towards it. You can see it here.

I’d love to have a crack at replicating the steering behavior as that fits with my game idea, but I’m not too well-versed in vector math. Can you give any pointers as to where I should begin?


Rilic | 2021-07-07 09:38

the first link dont work.
I dont know the game and the video isnt helping. Do you have a specific problem with your code or vector-math?

klaas | 2021-07-09 19:43

:bust_in_silhouette: Reply From: Rilic

I answered my own question here, though the question I asked was really badly written in retrospect. I just wanted to keep the speed of the player up while turning, and have turning steer towards the input direction on the joystick rather than lerp towards it and slide.

Keeping speed up while running:
Instead of what I was doing before, which was moving the player towards a lerped version of the velocity, I tracked speed as a separate variable. From there, I lerped the speed and simply multiplied the direction vector by that speed amount:

# Lerp run_speed
run_speed = lerp(run_speed, max_run_speed * step, accel * delta)

# Apply run_speed to direction, creating velocity
velocity = direction * run_speed

step is just the input strength of the controller, being a number between 0 and 1. If your game is designed just for keyboard use, you can leave it out.

This makes the player’s speed stay high while turning and go down over time if there is no input, but the turning is still instant with no “steering” effect.

Achieving velocity steering:
All I had to do for this was track the direction of the player as another separate variable and have that lerp towards the input direction with the extra variable turn_speed:

# Steer the real direction towards the mapped direction
direction = direction.linear_interpolate(input_direction, turn_speed * delta)
direction = direction.normalized()

This does create a problem where the player won’t turn immediately if the input is too sharp, such as holding W to holding S, but that can be solved later by using a “turn around” animation where the player skids to a halt and resumed in the other direction. That or maybe someone else can come up with a better method than mine here.