top down car physics

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By gtspeedster
:warning: Old Version Published before Godot 3 was released.

Hey guys! I’ve been trying to figure out how to make a 2d car with a top-down perspective drift, but i can’t figure out how… If anyone could give me a hint as of how to do it, it would be very appreciated.

Thanks!

:bust_in_silhouette: Reply From: mollusca

There are many ways to approach this, depending on how realistic you want to go. The most simple solution seems to be to start with a Rigidbody2D with an Asteroids-style control setup and use a force proportional to the orthogonal velocity to simulate tire friction. I wanted to test this so here’s a basic setup:

extends RigidBody2D

var steering_com = 0.0
var force_com = 0.0

func _ready():
    set_process_input(true)
    set_fixed_process(true)
    var shape = RectangleShape2D.new()
    shape.set_extents(Vector2(8, 20))
    add_shape(shape)

func _fixed_process(delta):
    var tf = get_global_transform()
    var vel = get_linear_velocity()
#	get the orthogonal velocity vector
    var right_vel = tf.x * tf.x.dot(vel)
#	decrease the force in proportion to the velocity to stop endless acceleration
    var force = force_com - force_com * clamp(vel.length() / 400.0, 0.0, 1.0)
    var steering_torque = steering_com
    if tf.y.dot(vel) < 0.0:
#	if reversing, reverse the steering
        steering_torque = -steering_com
#	make reversing much slower
        if force_com <= 0.0:
            force *= 0.1
#   apply the side force, the lower this is the more the car slides
#	make the sliding depend on the power command somewhat
    apply_impulse(Vector2(), -right_vel * 0.07 * clamp(1.0 / abs(force), 0.01, 1.0))
#  
    apply_impulse(Vector2(), tf.basis_xform(Vector2(0, force)))
#	scale the steering torque with velocity to prevent turning the car when not moving
    set_applied_torque(steering_torque * vel.length() / 200.0)

I left out the input processing, but I used 8.0 and -12.0 for power (force_com) and -512 and 512 for steering (steering_com). Gravity scale is set to 0. The various constants can be tweaked to change the behavior of the car.
There’s of course a lot you could do to make the car more fun/realistic to drive like tweaking the side-force and angular damping, smoothing the throttle when using a keyboard etc. At the very least you’d need to handle different road-surfaces somehow.
Maybe a more realistic approach would be to use one rigidbody for each wheel and one for the chassis, there’s some Box2D examples that do this.

Thank you so much for yout answer! I did indeed based my movement with an asteroid-like movement style, and I’ve found some info on this site : physics - Creating sideways friction in a 2D top down racer - Game Development Stack Exchange
but I’ll look into your methode and try to make my movement feel just right

gtspeedster | 2017-06-30 05:06

Hi Sir

can you revise your code to implement for area2d node

kocagozhkn | 2018-03-14 10:57

Would be great if someone could update this to 3.1, as I’m getting errors:

Method ‘add_shape’ is not declared in the current class

I also had to remove the set_fixed_process() call.

oskfo | 2019-08-10 09:42