B-rad
B-rad

Reputation: 1

How would i make my character slow down to a stop rather than immediately stop

I'm very new to programming and a using a tutorial I found to create the movement for my first game. it works fine for movement except that the character will stop abruptly is there a way to slowly decrease the velocity when an input is not being pressed. similar to quake for example.

 direction.z = Input.get_action_strength("move_backward")-Input.get_action_strength("move_forward")
 direction = direction.normalized()
 direction = direction.rotated(Vector3.UP,rotation.y)
 velocity.x = direction.x * movementSpeed
 velocity.z = direction.z * movementSpeed
 move_and_slide(velocity,Vector3.UP)

https://youtu.be/vEuR-Bo0feY here is the video for reference

Upvotes: 0

Views: 3942

Answers (1)

Theraot
Theraot

Reputation: 40295

Get the velocity that move_and_slide returns:

velocity = move_and_slide(velocity,Vector3.UP)

Which is the velocity after dealing with slides and collisions. And we will reduce it:

velocity -= velocity * min(delta/stop_time, 1.0)

Where stop_time is a variable that controls how fast you want it to stop in seconds (the same units of delta). So, if stop_time = 1.0, it will stop after one second. Tweak it to what you want. You may also hard-code the value if you prefer, but I'm suggesting to use a variable.

Now, idea is that we will keep the velocity for the next time _physics_process runs, and only set it to full movementSpeed when there is input. So you can check if direction is zero, and if it is, don't change velocity.

Something like this:

if direction.z != 0:
    direction = direction.normalized()
    direction = direction.rotated(Vector3.UP,rotation.y)
    velocity.x = direction.x * movementSpeed
    velocity.z = direction.z * movementSpeed

velocity = move_and_slide(velocity,Vector3.UP)
velocity -= velocity * min(delta/stop_time, 1.0)

By the way, if you will also add gravity, I suppose you don't want the fall to decelerate too. So, you may want to only want to apply that on the x and z. The good news that you can do it per component:

if direction.z != 0:
    direction = direction.normalized()
    direction = direction.rotated(Vector3.UP,rotation.y)
    velocity.x = direction.x * movementSpeed
    velocity.z = direction.z * movementSpeed

velocity = move_and_slide(velocity,Vector3.UP)
var slowdown := min(delta/stop_time, 1.0)
velocity.x -= velocity.x * slowdown
velocity.z -= velocity.z * slowdown

By the way, multiply gravity by delta when applying to velocity.


And you may not want that linear deceleration but some custom easing. You can accomplish that like this:

var slowdown := ease(min(delta/stop_time, 1.0), easing_curve)

Where easing_curve defines the curve used for easing, see cheat sheet.

For more complex behaviors you will want to use a Tween.

Upvotes: 2

Related Questions