If friction, drag, etc are all forces that of whom’s direction is always opposite to the applied force, then, since we already have calculated their magnitude, we should already have more than enough information to “apply” these forces.
Do you want to get from force to velocity? That way you just input the velocity into the bodymovers?
If thats the case, then thats pretty simple
force = mass * accerlation
accerlation = velocity / time
force = mass * velocity / time
force / mass = velocity / time
(force * time) / mass = velocity
We basically treat the surface as having a constant density (airs density) then multiply that by the velocity. From there we can slow down it by multiplying its surface area by the density vector
This field is also known as “Computational Fluid Dynamics” not to be confused with the wave equation
There’s BodyPosition and a BodyVelocity? That doesn’t make a ton of sense. How can it apply a static position while also setting a velocity?
You’ll probably either need to:
Contact the creator of this model for help, or
Find the places in the model’s code where these (four?) body movers’ properties are changed, and post that code here.
Because the answer to your questions is “find the places where they set the properties, and tweak those lines to set slightly different properties that take into account more forces”. I personally don’t want to download a random model and hunt around code that neither of us wrote. But if you were to post short existing code snippets, I’m sure more people would be glad to help!
local function UpdateThruster(thruster)
--Make sure we have a bodythrust to move the wheel
local bodyThrust = thruster:FindFirstChild("BodyThrust")
if not bodyThrust then
bodyThrust = Instance.new("BodyThrust", thruster)
end
--Do some raycasting to get the height of the wheel
local hit, position = Raycast.new(thruster.Position, thruster.CFrame:vectorToWorldSpace(Vector3.new(0, -1, 0)) * stats.Height.Value)
local thrusterHeight = (position - thruster.Position).magnitude
if hit and hit.CanCollide then
--If we're on the ground, apply some forces to push the wheel up
bodyThrust.force = Vector3.new(0, ((stats.Height.Value - thrusterHeight)^2) * (force / stats.Height.Value^2), 0)
local thrusterDamping = thruster.CFrame:toObjectSpace(CFrame.new(thruster.Velocity + thruster.Position)).p * damping
bodyThrust.force = bodyThrust.force - Vector3.new(0, thrusterDamping.Y, 0)
else
bodyThrust.force = Vector3.new(0, 0, 0)
end
--Wheels
local wheelWeld = thruster:FindFirstChild("WheelWeld")
if wheelWeld then
wheelWeld.C0 = CFrame.new(0, -math.min(thrusterHeight, stats.Height.Value * 0.8) + (wheelWeld.Part1.Size.Y / 2), 0)
-- Wheel turning
local offset = car.Chassis.CFrame:inverse() * thruster.CFrame
local speed = car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity)
if offset.Z < 0 then
local direction = 1
if speed.Z > 0 then
direction = -1
end
wheelWeld.C0 = wheelWeld.C0 * CFrame.Angles(0, (car.Chassis.RotVelocity.Y / 2) * direction, 0)
end
wheelWeld.C0 = wheelWeld.C0 * CFrame.Angles(rotation, 0, 0)
end
end
--A simple function to check if the car is grounded
local function IsGrounded()
local hit, position = Raycast.new((car.Chassis.CFrame * CFrame.new(0, 0, (car.Chassis.Size.Z / 2) - 1)).p, car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(0, -1, 0)) * (stats.Height.Value + 0.2))
if hit and hit.CanCollide then
return(true)
end
return(false)
end
--local oldCameraType = camera.CameraType
--camera.CameraType = cameraType
--spawn(function()
while game:GetService("RunService").Heartbeat:wait() and car:FindFirstChild("DriveSeat") and character.Humanoid.SeatPart == car.DriveSeat do
--game:GetService("RunService").RenderStepped:wait()
if IsGrounded() then
if movement.Y ~= 0 then
local velocity = humanoidRootPart.CFrame.lookVector * movement.Y * stats.Speed.Value
humanoidRootPart.Velocity = humanoidRootPart.Velocity:Lerp(velocity, 0.1)
bodyVelocity.maxForce = Vector3.new(0, 0, 0)
else
bodyVelocity.maxForce = Vector3.new(mass / 2, mass / 4, mass / 2)
end
local rotVelocity = humanoidRootPart.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value / 50, 0, -humanoidRootPart.RotVelocity.Y * 5 * movement.Y))
local speed = -humanoidRootPart.CFrame:vectorToObjectSpace(humanoidRootPart.Velocity).unit.Z
rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y)
if math.abs(speed) > 0.1 then
rotVelocity = rotVelocity + humanoidRootPart.CFrame:vectorToWorldSpace((Vector3.new(0, -movement.X * speed * stats.TurnSpeed.Value, 0)))
bodyAngularVelocity.maxTorque = Vector3.new(0, 0, 0)
else
bodyAngularVelocity.maxTorque = Vector3.new(mass / 4, mass / 2, mass / 4)
end
humanoidRootPart.RotVelocity = humanoidRootPart.RotVelocity:Lerp(rotVelocity, 0.1)
--bodyVelocity.maxForce = Vector3.new(mass / 3, mass / 6, mass / 3)
--bodyAngularVelocity.maxTorque = Vector3.new(mass / 6, mass / 3, mass / 6)
else
bodyVelocity.maxForce = Vector3.new(0, 0, 0)
bodyAngularVelocity.maxTorque = Vector3.new(0, 0, 0)
end
for i, part in pairs(car:GetChildren()) do
if part.Name == "Thruster" then
UpdateThruster(part)
end
end
end
for i, v in pairs(car:GetChildren()) do
if v:FindFirstChild("BodyThrust") then
v.BodyThrust:Destroy()
end
end
bodyVelocity:Destroy()
bodyAngularVelocity:Destroy()
--camera.CameraType = oldCameraType
script:Destroy()
--end)