How to find the velocity at a specific point on a RigidBody2d

Godot Version

4.3.stable

Question

Hi everyone, I’m currently trying to build a 2d car simulator, that simulates the grip of the tires.
My method for simulating steering that I’m trying to do is based on this video, where basically a force is applied in the opposite direction of the lateral force on the tire. However, I can’t figure out how to find the force vector over each tire. I’m using the “bicycle” model to simulate the car, meaning it only has 2 wheels if that makes sense. Here’s my current code, I’m pretty new to godot so apologies if I’m being stupid :slight_smile:

extends RigidBody2D

const WHEELBASE = 100 # The distance between the center of the front and rear wheel (in pixels)

const TIRE_GRIP_MAX = 10.0 # The point when the transition is made between static and kinetic friction
const GRIP_FACTOR_SLIDING = 3.0 # The amount of grip that sliding takes up
const GRIP_FACTOR_ACCELERATION = 5.0  # The amount of grip that acceleration takes up
var normal_force = 10.0 # The support force - affected by downforce and weight
var sliding_f = 0.0 # The amount of lateral force on the front tire
var sliding_r = 0.0 # The amount of lateral force on the rear tire

var acceleration_f = 0.0 # The amount of acceleration being applied to the front tire
var acceleration_r = 0.0 # The amount of acceleration being applied to the rear tire
var direction_f = 0.0 # The direction that the front wheel is pointing in
var direction_r = 0.0 # The direction that the rear wheel is pointing in

var steering_angle = deg_to_rad(20.0) # The maximum that the wheel turns when steering

# Called when the node enters the scene tree for the first time.
func _ready():
	linear_damp = 0.1
	angular_damp = 0.15


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta):
	# Inputs
	if Input.is_action_pressed("accelerate"):
		acceleration_f = 50.0
	elif Input.is_action_pressed("brake"):
		acceleration_f = -30.0
	else:
		acceleration_f = 0.0
	
	if Input.is_action_pressed("turn_left"):
		direction_f = -steering_angle
	elif Input.is_action_pressed("turn_right"):
		direction_f = steering_angle
	else:
		direction_f = 0.0

	# Front tire
	# Apply a force in the direction the tire is facing, offset to the location of the tire
	apply_force(angle_to_vector2(acceleration_f, 0).rotated(rotation + direction_f), Vector2((WHEELBASE / 2), 0))
	# Apply a force in the opposite direction of the lateral force
	
	# Rear tire
	# Apply a force in the direction the tire is facing, offset to the location of the tire
	apply_force(Vector2(acceleration_r, 0).rotated(rotation + direction_r), Vector2((WHEELBASE / -2), 0))
	# Apply a force in the opposite direction of the lateral force

if you override

_integrate_forces(state: PhysicsDirectBodyState2D)

in your RigidBody2D you get access to the PhysicsDirectBodyState2D object which has a method

get_velocity_at_local_position(local_position: Vector2)

Souns like this is what you need.
Here are the relevant doc pages:

1 Like