How to calculate traction? (physics)

For my car traction does not exist except when steering(centripetal force) as it is vector force based. Say if my car was suddenly knocked by an external force, it starts spinning and it no longer moves in a perfect direction.

1 Like

Do you have a BodyGyro or AngularOrientation in your car for steering?
We’ll need a better description than “it is vector force based” to get an idea of how you are making the car move and turn.

you literally don’t though… Do you even get what traction is? Anyways the angular velocity is calculated via the centripetal force formula Fc = mrw^2 rearranged and then applied on an angularbodyvelocity.

I get what traction is, but you didn’t really explain that you are using a formula to calculate the values for a BodyAngularVelocity to turn.

Have you tried changing the Friction and Density values in the wheels using BasePart | Roblox Creator Documentation?

I don’t build scripted vehicles, I use physical constraints for mine.
I’ve found that having wheels with a higher Density and Friction increases traction.

What do you not get of “vector force based” it doesn’t collide with the ground…

Give it inertia to make it harder to move, You can get the inertia with with

local inertia = angular_momentum / angular_velocity

which is:

local inertia = (BasePart:GetMass() * BasePart.Angular_Velocity) / BasePart.Angular_Velocity

aka

local inertia = BasePart:GetMass()

also as centripetal force is perpendicular to the velocity the force’s direction should be based on its CFrame’s RightVector (if the car is moving relative to its LookVector), just in case that also is a problem

Friction is also calculated by
ÎĽN which is
ÎĽ = coefficient of friction
N = the normal force, (calculable through a raycast downward based on the car wheel’s direction to get the normal direction)

Wouldn’t it be better to make an opposing force to increase traction?

Yes as traction is a form of friction between wheels and a surface

1 Like

I get what “vector force based” means, but did you take into account all the possible ways (scripted, physical, and combinations of both) that vehicles can be made in Studio in your first posts?

When you stated traction (the adhesive friction of a body on some surface, as a wheel on a rail or a tire on a road) in your original post I assumed that you were using some kind of physical movement between 2 touching Parts.

I can’t guess how everyone handles every different possibility in all the items they build and post on here for troubleshooting, so my assumptions are valid. I was trying to solve your issue with very little information from your end.

I implied that there was no current traction therefore touching parts would instantly be dismissed as it would cause traction…

The traction is just friction (with cars the calculations are much more complex, but this is only a little different). Kinetic friction is constant * normal force. That basically just means you’ll need to get the normal force then:

  • Use a BodyAngularVelocity
  • If the assembly’s angular velocity is greater 0 (probably something a touch higher than 0 for rounding)
    • Enable the AngularVelocity with the max force (only on the Y axis) set to the desired resistive force (normal * constant). The constant is based on real physics, I’d just find a number that works well. Noraml force should (most of the time) be equal to gravity * mass. Check if the car is on the ground though.

It’s quite helpful to know how you’re making your car move. A lot of cars just directly set the physics values of the assembly. VectorForces are some of the new weird BodyMovers that not many people use.

A VectorForce just applies a force in a direction. You can rig a car and have it touch the ground but still use a VectorForce to move it.

You said that traction only exists when steering in the form of centripetal force. IRL that’s from traction, as you said, so it wasn’t necessarily clear that you meant it wasn’t from traction, but from a force meant to simulate traction.


Having programming problems can be frustrating, but try not to take it out on nice, capable people just trying to help.


There are also some great tutorials on the internet. Game cars are meant to be different from real cars, and simplifying the physics down to what’s important is useful too. Here is a pretty good tutorial I found:

(There are probably some newer ones too :slight_smile:)

1 Like

Make the Car anchored and handle velocity and force through variables.
Force = mass * acceleration
and acceleration is a vector so the mass is the scalar quantity that is multiplied to the acceleration.
If you have a force that is needed to be applied then you have

local mass: number

and

local force: Vector3

therefore to apply the acceleration needed for the car to move, divide the applied force by the mass of the car

local acceleration = force / mass --which is a Vector3 that will be added to the velocity as acceleration

As for friction,
we first need the normal force which is found by getting the normal:

local gravitational_constant = 9.809

local params = RaycastParams.new()
params.FilterDescendantsInstances = {car}
params.FilterType = Enum.RaycastFilterType.BlackList

local from = car.Position
local to = car.CFrame.Upvector * -(car.Size.Y / 2 + ray_extenstion) --ray extenstion like 2?
local normal_force
local material
local hit = workspace:Raycast(from, to, params)
if hit then
  normal_force = hit.Normal * gravitational_constant * car:GetMass() * hit.Normal:Dot(Vector3.new(0, 1, 0)) --[[
this gets the normal force 's direction, then since the normal force is from Newton's third law that every force has a force of the same magnitude in the opposite direction
the force here is weight which on earth is mass * 9.809 (downwards) but if the weight is perpendicular to the floor's normal then there is no force being applied on the slope 
which is found from the cosine of the angle between upwards and the floor's normal
which is found from the dot product of the two unit vectors (vectors with a magnitude of 1) 
which gives a value between -1 and 1 with 0 being two perpendicular unit vectors
--]]
  material = hit.Material
else
  normal_force = Vector3.new(0, 1, 0) * gravitational_constant * car:GetMass()
  material = Enum.Material.Air
end

local cofficient = --[[test the material against materials that will be higher or lower friction, but the variable should be between 0 and 1 and in air, 0, I think that you should use a table with keys for certain values like
{
[Enum.Material.Fabric] = 1,
[Enum.Material.Air] = 0,
[Enum.Material.Plastic = 0.6]
}
keep trying the values until you get values that feel right.--]]

local friction = coefficient * (-car.CFrame.LookVector * (normal_force.magnitude))

local acceleration = friction / car:GetMass()

And I think that is how to do it, the same holds true even if you do not wish to use variables.

1 Like