r/godot•
atari_eric

Top-down car physics and Godot

Help

I am trying to implement a top-down car game in Godot using this tutorial as a basis, but Godot handles physics a little bit differently than Box2D, which the tutorial uses (Godot doesn't have native torque handling, for instance - though you can derive it) and I'm having some issues actually implementing a tire (it turns okay, but moving it makes it behave weird - it either rocks in place, or zooms off at an odd angle); I was wondering if anyone else had tried making a top-down car app or had any pointers dealing with the physics engine...

Posted Jul 19, 2015, 10:58 PM UTC

41
atari_ericOP•

Here is the code I tried using:

extends RigidBody2D

func _ready():
	set_fixed_process(true)

func ApplyForce(forceVector, delta):
#	apply_impulse(Vector2(0,0), forceVector * delta) 

	var currentForce = get_applied_force()
	currentForce += forceVector
	set_applied_force(currentForce)

const TORQUEMULT = 100

func ApplyTorque(torque, delta):
	apply_impulse(Vector2(0,TORQUEMULT), Vector2((torque * delta), 0)) 
	apply_impulse(Vector2(0,-TORQUEMULT), Vector2(-(torque * delta), 0)) 

const MAXLATERALIMPULSE = 2.5
const ANGULARDAMPENING = 2.0
const ROLLINGRESISTANCE = 2.0

const MAXFORWARDSPEED = 10000
const MAXREVERSESPEED = 2000
const MAXDRIVEFORCE = 100
const MAXSTEERINGTORQUE = 500

func ResistLateralSkid(rightVector):
	var lateralImpulse = -rightVector * get_mass()
	var impulseLength = lateralImpulse.length()
	if (impulseLength > MAXLATERALIMPULSE):
		lateralImpulse *= MAXLATERALIMPULSE / impulseLength
	apply_impulse(Vector2(0,0), lateralImpulse)
	
func ResistSteeringTorque(): 
	set_angular_damp(ANGULARDAMPENING)	

func ResistRolling(forwardVector, delta):
	ApplyForce(forwardVector * -ROLLINGRESISTANCE, delta)

func UpdateDrive(forwardNormal, speed, delta):    
#	var desiredSpeed = 0
#	if(Input.is_action_pressed("ui_up")):
#		desiredSpeed = MAXFORWARDSPEED
#	if(Input.is_action_pressed("ui_down")):
#		desiredSpeed = -MAXREVERSESPEED
#	
#	var forceMagnitude = 0 
#	if(speed < desiredSpeed):
#		forceMagnitude = MAXDRIVEFORCE 
#	if(speed > desiredSpeed):
#		forceMagnitude = -MAXDRIVEFORCE 
	
	var forceMagnitude = 0 
	if(Input.is_action_pressed("ui_up")):
		forceMagnitude = MAXDRIVEFORCE
	if(Input.is_action_pressed("ui_down")):
		forceMagnitude = -MAXDRIVEFORCE		

	if (forceMagnitude < 0.0 or forceMagnitude > 0.0):
		ApplyForce(forceMagnitude * forwardNormal, delta)	

func UpdateSteering(delta):
	var desiredTorque = 0.0	
	if(Input.is_action_pressed("ui_left")):
		desiredTorque = MAXSTEERINGTORQUE
	if(Input.is_action_pressed("ui_right")):
		desiredTorque = -MAXSTEERINGTORQUE

	if (desiredTorque < 0.0 or desiredTorque > 0.0):
		ApplyTorque(desiredTorque, delta)

func _fixed_process(delta):
	# needed values
	var rotation = get_rot() # global?
	var linearVelocity = get_linear_velocity() # global?
	var forwardNormal = Vector2(0,1).rotated(rotation)
	var rightNormal = Vector2(1,0).rotated(rotation)
	var forwardVelocity = forwardNormal.dot(linearVelocity) * forwardNormal
	var rightVelocity = rightNormal.dot(linearVelocity) * rightNormal

	UpdateDrive(forwardNormal, forwardVector.length(), delta)
	UpdateSteering(delta)
	ResistLateralSkid(rightVector)
	ResistSteeringTorque()
	ResistRolling(forwardVector, delta)
1