BodyForce causes my car to drift

So here is the very low poly car I have made. Everything is currently welded together and I am planning on animating the tyres.

Currently it drives by detecting keyboard input and applying a BodyForce to accelerate the car forwards (using look vector).

Turning is done with BodyAngularVelocity. This works fairly well, however there is an issue with turning at a speed.

Say my car is moving forward at a fast speed:


And then it decides to turn in one direction

As there is no friction from the tyres, the red force keeps acting and the car drifts in the red direction, when ideally I only want forces to act in the blue direction. After a while the drifting stops and it only drives towards blue however the red force still acts for a longish time.

I’ve considered applying forces in another direction to simulate friction but it seems a bit hacky. and also might decelerate the blue force.

Any help would be appreciated :slight_smile:

1 Like

You need to apply a centripetal force as well as your driving force. Each step, as well as applying the red force in the lookVector, you need to apply the centripetal force in either the rightVector or -rightVector.

The amount of the centripetal force is based on your speed and how tightly you want the radius of the turn. It will be related to how quickly you’re turning using the BodyAngularVelocity.

CentripetalForce = mass * ( linearVelocity ^ 2 ) / radius

Where mass is the mass you get from :GetMass(), linearVelocity is your lookVector velocity in studs per second and radius in studs.

If you know the angular velocity and want to work from that instead of radius, you can replace linearVelocity / radius with angularVelocity:

CentripetalForce = mass * linearVelocity * angularVelocity

Where angularVelocity is in radians per second.

Hope that helps. Here’s a few links that might explain further:

edit: Made the diagram a bit more detailed. Your BodyForce should exert a force vector that is the vector addition of the centripetal and driving forces.

15 Likes

Ah yes! All looks very familiar from my Physics finals last week. I was having to do the same but with planets and gravity.

This will be very helpful thanks, I will try it later when I am free :slight_smile: I appreciate such a detailed answer.

1 Like

Just added it in an it works like a dream!

Now I can turn into the petrol station without drifting and causing a horrible explosion :+1:

4 Likes

Glad to hear it :slightly_smiling_face: safety first

2 Likes

Remember Newton’s First Law in the future - a body in motion, stays in motion!

2 Likes

Yee boi. I guess a lot of Newton’s third law applies here too

All three apply in pretty much every situation. Second law is used to derive the centripetal force equation where the sum of the forces is equal to the rate of change of momentum that you’re trying to create when changing the car’s motion. F=d(mv)/dt which is simplified for a constant mass to F=ma.

1 Like

@BanTech could you explain this a bit more simply please? I’m not familiar with rightvector or lookvector and I happen to have the same issue with my car, except it uses BodyThrust to drive. Any help would be appreciated, thanks

Circular motion and centripetal force can be tricky to explain. I think the circular motion resource I linked to is probably better at explaining than I am, if my original answer didn’t convey it fully.

The main difference when working with BodyThrust is that the force is in local object space rather than world space, so it’s a lot simpler. Centripetal force is applied as the X number in the thrust vector, and the forward acceleration is applied as the Z number in the thrust vector, regardless of orientation.

The RightVector and LookVector parts were to allow acceleration and centripetal force to be converted to world space based on the orientation of the vehicle.

3 Likes

Since this post is really old I do not expect you to answer @BanTech but I do have a issue with my current Boat system. Since I am not good at physic related stuff and still learn how they function / behave in certain situations I do not know whats causing the issue.

I do hope that you can help me finding a solution for the problem. I will include Videos and source code of mine later on to help with the investigation, if you decide to help.

Basically, whenever I turn my Boat without accelerating it its getting none stop faster and faster. It might be due to the calculation since the function is being executed with the .Stepped event from the “RunService”.

Another problem is when hitting objects with the boat its starting to freak out + backwards driving is also not possible since the calculation does not seem to effect the direction (backwards). This might also be caused by the calculation but as I said, I am not a expert at this kind of stuff. I would be glad for any help that I could recieve.

Forces used to get the Boat Moving:

  • VectorForce (Forwards & Backwards)
  • AngularVelocity (For Steering)
  • AlignPosition (To keep the Boat aligned to the dynamic waves)

image

Code (Sorry for the messy code, the whole structure will change in the final version + Variables like “Acceleration” and “ReversedAcceleration” are not final yet):

local _RS = game:GetService("RunService")
local RS = game:GetService("ReplicatedStorage")
local Seat = script.Parent.Drive
local Prox = script.Parent.IP.DriverProx

local WaveModule = require(RS.Modules.Ocean.Wave)
local CurrentSpeed = 0
local Acceleration = 20000
local ReversedAcceleration = -10000

Prox.Triggered:Connect(function(Player)
	Player.Character.HumanoidRootPart.CFrame = Seat.CFrame
end)


local function DriveBoat()
	local CentripetalForce = script.Parent.Base:GetMass() * Seat.Velocity.Magnitude * script.Parent.Base.AngularVelocity.AngularVelocity.Y
	if Seat.Throttle == 1 then
		CurrentSpeed = Acceleration
	elseif Seat.Throttle == -1 then
		CurrentSpeed = ReversedAcceleration
	else
		CurrentSpeed = 0
	end
	
	if Seat.Steer == 1 then
		script.Parent.Base.AngularVelocity.AngularVelocity = Vector3.new(0, -0.5, 0)
	elseif Seat.Steer == -1 then
		script.Parent.Base.AngularVelocity.AngularVelocity = Vector3.new(0, 0.5, 0)
	else
		script.Parent.Base.AngularVelocity.AngularVelocity = Vector3.new(0, 0, 0)
	end
	
	local BoatWaveHeight = WaveModule.GetHeightAtXZ(script.Parent.Base.Position)
	script.Parent.Base.VectorForce.Force = Vector3.new(CentripetalForce, 0, CurrentSpeed)
	script.Parent.Base.AlignPosition.Position = Vector3.new(0, BoatWaveHeight + 1, 0)
end

_RS.Stepped:Connect(DriveBoat)

Videos:
(I only pressed “D” at this point and it started to move (what it shoudn’t do)


(Not Pressing anything once I hit the object)

Best regards, Sxato