0 votes

Hello!

I found a script for simulating simple car physics and adapted it to my liking.

The problem is that I can't find a proper way to have the car collide with a staticbody and in turn change its velocity accordingly. Instead it keeps its speed, slides from the staticbody and continues on its way with the same speed.

I reckon I have to do something with whatever move_and_slide(move_vector) returns, but I just can't seem to figure it out. I'm so close to having the perfect car simulation I need for my game.

You can download the project here

extends KinematicBody2D

const DEBUG = true

export var max_speed_forward = 2000
export var max_speed_backwards = 500
export var accel := 1.0         # acceleration
export var momentum = 0.3     # momentum
export var deaccel_brake = 2 # brake force

var current_direction = Vector2(0, -1)

export var rotation_speed := 1.0

var current_speed = 0
var current_turn = 0

var handling_level = 0
var acceleration_level = 0
var topspeed_level = 0

var real_speed = 0

func perpendicular_vector(vec: Vector2):
    return Vector2(vec.y, -vec.x)

func _physics_process(delta):
    # Change forward velocity based on up and down input
    if Input.is_action_pressed("brake"):
        if current_speed < 0: # When we go forward
            current_speed += deaccel_brake * delta
        elif current_speed < 1: # When we go backwards
            current_speed += accel * delta
    elif Input.is_action_pressed("accelerate"):
        if current_speed > -1:
            current_speed -= accel * delta
    else: # When player isn't holding anything, deaccelerate
        if current_speed < -0.01: # When we go forward
            current_speed += momentum * delta
        elif current_speed > 0.01: # When we go backwards
            current_speed -= momentum * delta
        else: # STOP
            current_speed = 0

    # Setting the current turn direction
    if Input.is_action_pressed("steer_left"):
        current_turn = delta
    elif Input.is_action_pressed("steer_right"):
        current_turn = -delta
    else:
        current_turn = 0

    if DEBUG:
        if Input.is_action_just_pressed("up_handling"):
            handling_level += 1
            set_steering_angle()
        if Input.is_action_just_pressed("down_handling"):
            handling_level -= 1
            set_steering_angle()
        if Input.is_action_just_pressed("up_acceleration"):
            acceleration_level += 1
            set_acceleration()
        if Input.is_action_just_pressed("down_acceleration"):
            acceleration_level -= 1
            set_acceleration()
        if Input.is_action_just_pressed("up_topspeed"):
            topspeed_level += 1
            set_topspeed()
        if Input.is_action_just_pressed("down_topspeed"):
            topspeed_level -= 1
            set_topspeed()

    # Add a scaled down perpendicular vector of current dirrection to the direction.
    # This will result in changing the direction vector each frame when player is holding
    # right/left keys
    # Multypling by current speed is optional (This way you prevent turning around on one place)
    current_direction += perpendicular_vector(current_direction) * current_turn * rotation_speed * -current_speed

    # Normalize the vector, so the direction is preserved but size remains the same.
    # This prevents acceleration bug
    current_direction = current_direction.normalized()

    # Visual rotation of our kinematic body.
    rotation_degrees = rad2deg(current_direction.angle()) 

    # Application of the result movement
    var move_vector = current_direction * -current_speed * delta
    if current_speed > 0:
        move_vector *= max_speed_backwards
        real_speed = (current_speed * -max_speed_backwards) / 50

    else:
        move_vector *= max_speed_forward
        real_speed = (current_speed * max_speed_forward*-1) / 50

    move_and_slide(move_vector)

func set_steering_angle():
    rotation_speed = 1 + handling_level * 0.5

func set_acceleration():
    accel = 1 + acceleration_level * 0.25

func set_topspeed():
    max_speed_forward = 2000 + topspeed_level * 1000
Godot version v3.3.3
in Engine by (12 points)
edited by

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.