it is basically copied from the first video I linked.
if raycast then
local raycastDistance = (rayOrigin - raycast.Position).Magnitude
local springLength = math.clamp(raycastDistance - floatingHeight, 0, SuspensionMaxHeight)
local stifnessForce = Stiffness * (SuspensionMaxHeight - springLength)
local DampingForce = Damping * ((LastSuspensionLength[wheel] - springLength) / deltaTime)
local SuspensionForce = car.CFrame.UpVector * (stifnessForce + DampingForce)
local RotationsOnlyWheelDirCFrame = CFrame.lookAt(Vector3.zero,carCFrame.LookVector,carCFrame.UpVector)
local LocalVelocity = RotationsOnlyWheelDirCFrame:ToObjectSpace(CFrame.new(car:GetVelocityAtPosition(raycast.Position)))
local Xforce = carCFrame.RightVector * -LocalVelocity.x * friction
local Zforce = carCFrame.LookVector * LocalVelocity.z * (friction / 3)
local forwardForce = carCFrame.LookVector * 60
LastSuspensionLength[wheel] = springLength
car:ApplyImpulseAtPosition(SuspensionForce + Xforce + Zforce + forwardForce, raycast.Position)
else
LastSuspensionLength[wheel] = SuspensionMaxHeight
end
(forwardForce is just the force that makes the car go forward for testing purposes only.)
That’s the part if raycast is not nil and I have no idea how friction here is supposed work.
And I don’t know how to apply the physics formula for friction on floating object.