Godot Version
godot-4.2.2
Question
Hello,
I’m working on a 2D racing game and I can’t quite figure out how to properly implement a handbrake.
The handbrake works by simply lowering the value of “friction” and it works alright but the friction value doesn’t return to default when I let off the ebreak botton. That’s what I need help with, what can I do to make it so that the value resets to default after I disengage the handbrake? Here’s the relevant code:
func _physics_process(delta):
acceleration = Vector2.ZERO
get_input()
apply_friction()
calculate_steering(delta)
velocity += acceleration * delta
move_and_slide()
print(friciton)
func apply_friction():
if velocity.length() < 5:
velocity = Vector2.ZERO
var friciton_force = velocity * friciton
#var ebreak_force = velocity * ebreak_friction
var drag_force = velocity * velocity.length() * drag
acceleration += drag_force + friciton_force
func get_input():
if Input.is_action_pressed("right"):
turn += 1
if Input.is_action_pressed("left"):
turn -= 1
if Input.is_action_pressed("up"):
acceleration = transform.x * engine_power
if Input.is_action_pressed("down"):
acceleration = transform.x * breaking
#engaging the handbrake
if Input.is_action_pressed("ebreak"):
acceleration = transform.x * handbreak
friciton = ebreak_friction
and here’s the full code:
extends CharacterBody2D
var wheel_base = 70 # Distance from front to rear wheel
var steering_angle = 60 # Amount that front wheel turns, in degrees
var engine_power = 600
@export var friciton = -0.9
var ebreak_friction = -0.4
var drag = -0.001
var breaking = -450
var handbreak = -300
var max_speed_rev = 250
var slip_speed = 400
var front_slip_speed = 300
var understeer = 20
var traction_fast = 0.1
var traction_slow = 1.0
@export var body: CharacterBody2D
var ebreak_check
var acceleration = Vector2.ZERO
var velo = Vector2.ZERO
var steer_angle
func _physics_process(delta):
acceleration = Vector2.ZERO
get_input()
apply_friction()
calculate_steering(delta)
velocity += acceleration * delta
move_and_slide()
print(friciton)
func apply_friction():
if velocity.length() < 5:
velocity = Vector2.ZERO
var friciton_force = velocity * friciton
#var ebreak_force = velocity * ebreak_friction
var drag_force = velocity * velocity.length() * drag
acceleration += drag_force + friciton_force
func get_input():
var turn = 0
if Input.is_action_pressed("right"):
turn += 1
if Input.is_action_pressed("left"):
turn -= 1
#understeer
if velocity.length() < front_slip_speed:
steer_angle = turn * deg_to_rad(steering_angle)
elif velocity.length() > front_slip_speed:
steer_angle = turn * deg_to_rad(understeer)
#understeer_end
if Input.is_action_pressed("up"):
acceleration = transform.x * engine_power
if Input.is_action_pressed("down"):
acceleration = transform.x * breaking
if Input.is_action_pressed("ebreak"):
acceleration = transform.x * handbreak
friciton = ebreak_friction
func calculate_steering(delta):
var rear_wheel = position - transform.x * wheel_base / 2.0
var front_wheel = position + transform.x * wheel_base / 2.0
var traction = traction_slow
#oversteer
if velocity.length() > slip_speed:
traction = traction_fast
rear_wheel += velocity * delta
front_wheel += velocity.rotated(steer_angle) * delta
var new_heading = (front_wheel - rear_wheel).normalized()
var d = new_heading.dot(velocity.normalized())
if d > 0:
velocity = velocity.lerp(new_heading * velocity.length(), traction)
if d < 0:
velocity = -new_heading * min(velocity.length(), max_speed_rev)
rotation = new_heading.angle()
majority of the code is basically coppied from here:
https://kidscancode.org/godot_recipes/3.x/2d/car_steering/