Stabilizing Hover

#1

For whatever reason I cannot figure out how to keep this thing at a constant hover rather than this crazy bounce. Anyone handy with physics?



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

Stabilize.rbxl (18.0 KB)

4 Likes
#2

Have you tried adding a bodyforce that pushes upwards with the force of the equivalent of gravity * the part’s mass?

1 Like
#3

That would just results an object that hover perfectly still till another force acts upon it.

Edit: would also fly infinitely upward as soon as one of the “Thrusters” got close to the ground.

1 Like
#4

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?

1 Like
#5

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

1 Like
#6

Why not use a bodygyro to keep it from spinning around, and a bodyposition to stabilize it? You can also use a bodyposition instead of a bodythrust (Message me on the devforum for more info on bodyposition instead of bodythrusts). And I haven’t the time to test a suspension with a bodyposition instead of a bodythrust because I only
just accomplished a simple system like this today. My system does not use raycasting either… It just uses ‘bottompart:GetTouchingParts()’. You can message me on the devforum, and when I have the time (Or if I am awake, and my suspension system is fully done lol) I will give you or @snorebear a copy so you may learn, and use it freely ;).

2 Likes
#7

The only disadvantage of using Bodypositions instead of bodythrusts, is that they have lots of strength. For example: If you put a large part on the thruster, the thruster will act as if the part on top of it is is weightless. (That might be either the way bodypositions work, or because my bodyposition’s maxforce properti is being set to ‘inf’)

2 Likes
#9

Appreciate the suggestion but there is a reason I am going for the “more complicated system”.

2 Likes
#11

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.

Here’s a cool overview of the idea.

2 Likes
#12

So then my system would be unrealistic?

2 Likes
#13

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.

2 Likes
#14

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.

5 Likes
#16

What is CurrentDist, and LastDist, lastly what is delta?

1 Like
#17

Having some difficulties implementing this using what you have given. Did you implement this with the given studio file or your own?

2 Likes
#18

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.

2 Likes
#19

So that means the time between the last calculation and the current calculation?

1 Like
#20

Yes, in my code you see I signify Delta as local dt = wait()

2 Likes
#21

Also having difficulty implementing

2 Likes
#22

dt is argument to the function in Runservice

2 Likes
#23

@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.

2 Likes