Godot Version
v4.2.1
I am making a kart controller for a Mario Kart-like game, it is controlled by a sphere shaped rigidbody3D that rolls around and the kart mesh just follows it. I am fairly new to Godot and not familiar with how all of the physics and whatnot work so to get a basis for it, I copied and modified some scripts online. I then added a drift system which despite the probably very poorly written code, it works pretty well. The issue with the kart is that the RigidBody for whatever reason is very shaky and I can’t seem to figure out why. I have a suspicion its because of the friction code but I really have no clue…
Its kind of hard to explain so here’s a video example of what I’m talking about:
Here’s how the kart is set up:
kartFinal.tscn - Dukkart - Godot Engine 7_16_2024 10_06_10 AM|690x362
And here’s the code for it:
extends Node3D
@onready var ball = $ball
@onready var car = $Car
@onready var ray = $Car/RayCast3D
@onready var cam_pivot = $Car/CameraPivot
@onready var anim = $Car/AnimationPlayer
var sphereOffset = Vector3(0, -.19, 0)
var acceleration = 5
var steering = 25
var turnSpeed = .7
var turnStopLimit = .75
var sidewaysFriction = .8
var inputRange = 1.0
var drifting = false
var turnInput
var reversing = false
var driftDirection
var goRight
# Called when the node enters the scene tree for the first time.
func _ready():
ray.add_exception(ball)
func snap_position(t: Transform3D) -> void:
ball.global_transform = t
car.global_transform = t
ball.linear_velocity = Vector3.ZERO
ball.angular_velocity = Vector3.ZERO
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
var input = Input.get_vector("a","d","w","s")
var linear_velocity: Vector3 = ball.get_linear_velocity()
var local_linear_velocity: Vector3 = car.global_transform.basis.inverse() * linear_velocity
if drifting == false:
turnInput = -input.x
if linear_velocity.length() < 20:
ball.apply_central_force(car.global_transform.basis.z * input.y * acceleration)
if ball.linear_velocity.length() > turnStopLimit:
var new_basis: Basis = car.global_transform.basis.rotated(car.global_transform.basis.y, turnInput).orthonormalized()
var new_basis2: Basis = car.global_transform.basis.rotated(car.global_transform.basis.y, -turnInput).orthonormalized()
var turn_direction: float = -sign(local_linear_velocity.z)
print(turnStopLimit)
if reversing == false:
car.global_transform.basis = car.global_transform.basis.slerp(new_basis, turnSpeed * turn_direction * delta)
elif reversing == true:
car.global_transform.basis = car.global_transform.basis.slerp(new_basis2, turnSpeed * turn_direction * delta)
car.global_transform = car.global_transform.orthonormalized()
var new_basis = car.global_transform.basis.rotated(car.global_transform.basis.y, -input.x)
car.global_transform = car.global_transform.orthonormalized()
car.global_transform = car.global_transform.basis.slerp(new_basis, turnSpeed * delta)
var n: Vector3 = ray.get_collision_normal()
var xform: Transform3D = align_with_y(car.global_transform, n.normalized() )
car.global_transform = car.global_transform.interpolate_with(xform, 10.0 * delta)
var sideways_velocity: float = local_linear_velocity.x
var sideways_force: Vector3 = sideways_velocity * sidewaysFriction * -car.transform.basis.x
ball.apply_central_force(sideways_force)
if Input.is_action_just_pressed("drift"):
if driftDirection == 0:
turnInput = -input.x
anim.play("drifthop")
turnSpeed = 1
driftDirection = input.x
if driftDirection == 0:
turnInput = -input.x
elif driftDirection > 0:
turnInput = -input.x - 2
elif driftDirection < 0:
turnInput = -input.x + 2
print(driftDirection)
await get_tree().create_timer(.4).timeout
if Input.is_action_pressed("drift"):
drifting = true
if driftDirection == 0:
turnInput = -input.x
elif driftDirection <= 0:
turnInput = -input.x + .2
elif driftDirection >= 0:
turnInput = -input.x - .2
elif Input.is_action_just_released("drift"):
turnInput = -input.x
drifting = false
turnSpeed = .7
if Input.is_action_just_pressed("w"):
reversing = false
elif Input.is_action_just_pressed("s"):
reversing = true
car.transform.origin = ball.transform.origin + sphereOffset
func align_with_y(xform: Transform3D, new_y: Vector3) -> Transform3D:
xform.basis.y = new_y
xform.basis.x = -xform.basis.z.cross(new_y).normalized()
xform.basis = xform.basis.orthonormalized()
return xform
If anyone would be willing to help me with this it would be greatly appreciated!