I’m trying to make a topdown racing game but the movement is a bit off.
if direction:
# Get the angle to the desired direction
var target_angle = direction.angle()
# Smoothly rotate towards that angle
rotation = lerp_angle(rotation, target_angle, TURN_SPEED * delta)
if direction.x: #move_toward() dosent work with vectors so its been split into x and y
velocity.x = move_toward(velocity.x, max_speed*direction.x, 12.5)
if direction.y:
velocity.y = move_toward(velocity.y, max_speed*direction.y, 12.5)
#slowly move towards standing still
velocity.x = move_toward(velocity.x, 0, 1)
velocity.y = move_toward(velocity.y, 0, 1)
This works fine but it’s not exactly what i want and feels a bit off for a racing game.
right now when input is “Up” and switches to “Up + left” the player slows down. This is because the code does what its meant to do.
How can I make the movement more “drifty”
instead of immediately slowing down when changing directions it should happen more gradually? (if that makes sense)
First thing to do it to accelerate to your rotation instead of the input direction. That way the car accelerates down the forward axis like it would IRL.
This is a very accessible resource that goes in depth on top down car physics. TLDR, implement deceleration through friction (wheels and air) and implement variable traction based on speed.
There is a move_toward() function on the Vector2 class.
So your code could be simplified to
if direction:
# Get the angle to the desired direction
var target_angle = direction.angle()
# Smoothly rotate towards that angle
rotation = lerp_angle(rotation, target_angle, TURN_SPEED * delta)
# Move towards desired direction and speed
velocity = velocity.move_toward(max_speed*direction, 12.5)
#slowly move towards standing still
velocity = velocity.move_toward(Vector2.ZERO, 1)
But I would suggest making a couple more changes to the code, so that it goes towards the direction of the rotation, and not against it.
extends CharacterBody2D
const TURN_SPEED: float = 3.0
const MAX_SPEED: float = 200.0
const ACCELERATION: float = 3.0
const DECELERATION: float = 3.0
func _physics_process(delta: float) -> void:
var direction: Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down").normalized()
if direction:
# Get the angle to the desired direction
var target_angle: float = direction.angle()
# Smoothly rotate towards that angle
rotation = lerp_angle(rotation, target_angle, TURN_SPEED * delta)
# Get the angle to the desired direction
var target_velocity: Vector2 = transform.x * MAX_SPEED
# Move towards desired direction and speed
velocity = velocity.move_toward(target_velocity, ACCELERATION)
else:
#slowly move towards standing still
velocity = velocity.move_toward(Vector2.ZERO, DECELERATION)
move_and_slide()