• 3D
  • Add Jump and Drift to Arcade car (Kidscancode)

Hi, I'm a godot beginner and I have followed this simple car tutorial from kidscancode Arcade style car

extends Spatial

onready var ball = $Ball
onready var car_mesh = $CarMesh
onready var ground_ray = $CarMesh/RayCast

onready var right_wheel = $CarMesh/tmpParent/suv/wheel_frontRight
onready var left_wheel = $CarMesh/tmpParent/suv/wheel_frontLeft
onready var body_mesh = $CarMesh/tmpParent/suv/body

onready var num_cameras = $CarMesh/CameraPositions.get_child_count()
var current_camera = 0

var sphere_offset = Vector3(0, -1.0, 0)
var acceleration = 60
var steering = 21.0
var turn_speed = 5
var turn_stop_limit = 0.75

var speed_input = 0
var rotate_input = 0

var body_tilt = 25

func _ready():
	ground_ray.add_exception(ball)
	emit_signal("change_camera", $CarMesh/CameraPositions.get_child(current_camera))

func _physics_process(_delta):
	car_mesh.transform.origin = ball.transform.origin + sphere_offset
	ball.add_central_force(-car_mesh.global_transform.basis.z * speed_input)

func _process(delta):

	speed_input = 0
	speed_input += Input.get_action_strength("accelerate")
	speed_input -= Input.get_action_strength("brake")
	speed_input *= acceleration

	rotate_input = 0
	rotate_input += Input.get_action_strength("steer_left")
	rotate_input -= Input.get_action_strength("steer_right")
	rotate_input *= deg2rad(steering)
	
	right_wheel.rotation.y = rotate_input
	left_wheel.rotation.y = rotate_input

	if ball.linear_velocity.length() > turn_stop_limit:
		var new_basis = car_mesh.global_transform.basis.rotated(car_mesh.global_transform.basis.y, rotate_input)
		car_mesh.global_transform.basis = car_mesh.global_transform.basis.slerp(new_basis, turn_speed * delta)
		car_mesh.global_transform = car_mesh.global_transform.orthonormalized()
		var t = -rotate_input * ball.linear_velocity.length() / body_tilt
		body_mesh.rotation.z = lerp(body_mesh.rotation.z, t, 10 * delta)
		
	var n = ground_ray.get_collision_normal()
	var xform = align_with_y(car_mesh.global_transform, n.normalized())
	car_mesh.global_transform = car_mesh.global_transform.interpolate_with(xform, 10 * delta)
	
func align_with_y(xform, new_y):
	xform.basis.y = new_y
	xform.basis.x = -xform.basis.z.cross(new_y)
	xform.basis = xform.basis.orthonormalized()
	return xform

It's working so far and I have basic understanding on how the codes work but I want to learn how to expand this farther. for example How would I go about on adding the jump function or drift function? (like MarioKart) I have googled but they all seems to be for Kinematic3D node, not Spatial

Thanks

Well, its kinda harder to add jumping due to needing collision detection, which is probably why most use the KinematicBody node since it has functions to move and take the physics world into account.

For jumping with a Spatial node, you will need to apply a vertical velocity and gravity. You’ll want to have it where the detection method you are using for seeing the ground (a raycast, based on the code above) detects the ground you cancel out the vertical velocity and detect jumping input. Then, if the jump key is pressed, you set the vertical velocity to a big positive number. When the car is not on the ground, you’ll want to apply the vertical velocity and gravity, moving the car by the velocity amount and making the velocity get smaller and smaller. This should, I think, give you jumping.

To put it into pseudo code, it would look something like this:

var vertical_velocity = 0
const GRAVITY = 4.0

func _process(delta):
	# other code here
	if ground_ray.is_colliding() == true:
		vertical_velocity = 0
		if Input.is_action_just_pressed(“jump”):
			vertical_velocity = 100
			global_transform.origin.y += vertical_velocity * delta
	else:
		global_transform.origin.y += vertical_velocity * delta
		vertical_velocity -= delta * GRAVITY

I think that should work.

For drifting, that would requiring have velocity for horizontal movement, acceleration and deceleration. Right off I’m not 100% sure on how to program it though and you may want to look into using a KinematicBody or RigidBody node at that point, as it can help with a lot of the heavy lifting and physics calculations.

Also


This discussion was caught in the moderation queue since you have not confirmed your account yet.

Upon creating your account you should have received an account verification email. The confirmation email may have been incorrectly flagged as spam, so please also check your spam filter. Without confirming your account, future posts may also be caught in the moderation queue. You can resend a confirmation email when you log into your account if you cannot find the first verification email.

(Note: You do not need to repost, the discussion has been moved out and is visible now)

If you need any help, please let us know! You can find ways to contact forum staff on the Contact page. Thanks! :smile:

Thank you. FYI It flew up like a rocket plus messed up everything else with the car :#

As beginner I guess this tutorial isn't as easy to expand on. I will stick with learning KinematicBody as you said (I'm trying to learn different types of tutorial to see what I can do)

I hope you don't mind I mark this as unanswered in case someone else wanna try it

@Gowydot said: Thank you. FYI It flew up like a rocket plus messed up everything else with the car :#

You are welcome, though my apologizes that the code does not work as expected. For it flying up like a rocket, decreasing the vertical velocity strength (from 100 to something like 4 or 10) should make the car fly not as high. Though if it messes up everything else with the car, than I would say its not a viable solution.

As beginner I guess this tutorial isn't as easy to expand on. I will stick with learning KinematicBody as you said (I'm trying to learn different types of tutorial to see what I can do)

That is probably best, as using a physics node can help with some of the heavy lifting.

I hope you don't mind I mark this as unanswered in case someone else wanna try it

I do not mind at all! :smile:

Hi FYI again The guy posted his project file and I tried your code on it and it works! (with little tweaking)

if ground_ray.is_colliding() == true:
	vertical_velocity = 0
if Input.is_action_just_pressed("jump"):
	vertical_velocity = 40
	ball.global_transform.origin.y += vertical_velocity * delta

else:
	ball.global_transform.origin.y += vertical_velocity * delta
	vertical_velocity -= delta * GRAVITY

Thanks so much!! I will play around with this and see if I can make drifting function work somehow