local Force = script.Parent.Part:GetMass() * game.Workspace.Gravity * 1.5
local SuspensionHeight = 5;
local function Lerp(a, b, t)
return a * (1-t) + (b*t)
end
local function RayDown(Part)
local Cast = Ray.new(Part.CFrame.p,Vector3.new(0,-1,0).unit * SuspensionHeight);
return game.Workspace:FindPartOnRay(Cast,script.Parent)
end
while true do
local dt = wait()
for _,v in ipairs(script.Parent:GetChildren()) do
if v:FindFirstChild("Humanoid") then
local Part,Pos = RayDown(v.Head);
local CompressionRatio;
if Part and Pos then
CompressionRatio = (SuspensionHeight - (Pos - v.Head.Position).Magnitude)/SuspensionHeight
else
CompressionRatio = 0;
end
v.Name = string.format("%.2f",tostring(CompressionRatio));
v.Head.VectorForce.Force = Vector3.new(0,Lerp(v.Head.VectorForce.Force.Y, CompressionRatio * (Force/4),.8),0)
end
end
end
I’m confused. Isn’t that what you want? You stated a “constant hover”. Do you want a light bounce-like feature that looks like the car is moving slowly up and down?
The goal is to simulate suspension by applying an upward velocity on 4 different corners of the object based on how high above the ground each corner is. My problem is that I cannot figure out how to stabilize and keep it from bouncing all over the place
Well pretty much every high quality vehicle system from GTA to Jailbreak that is not over the top focused on physics calculations uses this method. It relies entirely on the physics engine and thus reacts to both expected and unexpected situations in a realistic manner.
I watched that video before and tried to apply it to Roblox and ended up having the same issues you have now. Hoping someone can aid you so they indirectly help me.
I used the following: Force=-(CurrentDist-MaxSpringLen)*Stiffness-Damping*(CurrentDist-LastDist)/delta
With: Damping = 2*math.sqrt(Stiffness)
to make it critically damped. We assume that mass of wheels is equal to 1 for simplicity.
It gave a perfect result.
CurrentDist = The distance between the “Thruster” and the ground
LastDist = The distance between the “Thruster” and the ground the last time it was calculated
Delta = Time in-between those two calculations.
@DragRacer31
CurrentDist is the current frame’s distance between the spring’s origin and the part below it.
LastDist is the CurrentDist of the last frame.
Using this avoids having to calculate the velocity using angular velocities off both the car’s axle and the hit part.
Delta is just the time difference between 2 frames.
@Spooks_HD@VineyardVine
I used a custom implementation. Just made a platform with a Root part in the center, welded 4 axles to it and binded the formula to Heartbeat for each axle.
Also, set the force to (0,0,0) when no surface is detected.
I remade the thing. You might need to make a lot of changes to the hit detection, make the wheels rotate and maybe rewrite the entire script to make it work like a real car, but the base is here.
Completely forgot to mention. You might want to lift the axles a few studs since they bounce into oblivion if they get too close to the ground. The model acts like a limiter in those cases.