You can write your topic however you want, but you need to answer these questions:
So basically I’m trying to make a hover craft, however i can not seem to get the physics down whatsoever.
Ive made 4 attempts each one building off the last after the 1st one
Here are the results that i recorded not in any particular order
function ptm() -- Ptm = PartMaker
local Part = Instance.new("Part")
Part.Anchored = true
Part.CanCollide = false
Part.Size = Vector3.new(1,1,1)
Part.Parent = script.Parent
return Part
end
local Run = game:GetService("RunService")
local Thrusters = {}
for i, v in pairs(script.Parent:GetChildren()) do
--spawn(function()
if v:IsA"Part" then
if v ~= script.Parent.PrimaryPart then
-- while wait() do
--
-- end
table.insert(Thrusters, v)
else
local BodyVelocity = Instance.new("BodyVelocity")
BodyVelocity.Parent = v
BodyVelocity.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
BodyVelocity.P = 10
spawn(function()
while wait() do
--BodyVelocity.Velocity = v.CFrame.LookVector * 0
end
end)
end
else
--return
end
--end)
end
for i, v in pairs(Thrusters) do
spawn(function()
-- local Part = ptm()
-- local Part2 = ptm()
-- local Part3 = ptm()
local BodyVeloicty = Instance.new("BodyVelocity")
BodyVeloicty.Parent = v
BodyVeloicty.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
local Dist
spawn(function()
while true do
print(v.Name, BodyVeloicty.Velocity)
print(math.ceil(Dist), math.floor(Dist), Dist)
wait(5)
end
end)
Run.Stepped:Connect(function()
local Mag = 500
local Power = script.Power.Value
local Velocity = script.Velocity.Value
BodyVeloicty.P = Power
local A = v.Position - Vector3.new(0,1,0)
local B = v.Position
local ray = Ray.new(B, B + (A - B).Unit * Mag )
local part, position = workspace:FindPartOnRayWithIgnoreList(ray, script.Parent:GetChildren())
if part ~= nil then
--[[spawn(function()
Part.CFrame = CFrame.new(position)
Part2.CFrame = CFrame.new(v.Position + Vector3.new(0,2,0))
Part3.Color = Color3.fromRGB(0,0,0)
Part3.CFrame = CFrame.new((v.Position + position)/2)
Part3.Size = Vector3.new(.1,(v.Position - position).Magnitude,.1)
end)--]]
Dist = (position - v.Position).Magnitude
if Dist <= 5 then
BodyVeloicty.Velocity = v.CFrame.UpVector * Velocity
elseif Dist > 5 then
BodyVeloicty.Velocity = v.CFrame.UpVector * -1
else
end
end
end)
end)
end
You should factor in the SurfaceNormal returned by raycasting in your velocity caclulations. You should also not do an if statement like that with the Dist, you should let the velocity slowly taper off when it gets farther away. I’d reccomend adding BodyGyro so you can have control of the vehicle’s rotation. If you’re going to be adding the ability to control it, then you should use AngularVelocity for steering and obviously the BodyVelocity for forward motion.
Also, I would reccomend having one Stepped connection for doing all the calculations.
I would go with what @EDMaster24 said. Also the force applied should follow the Inverse Square Law if you want to stay accurate to physics.
Here’s how I achieve cool looking hover physics:
Here’s an equation of how force would work this way: force = thrust - thrust/((distanceToFloor/hoverHeight)^2) + workspace.Gravity*totalMass
You should also disable the force if the distanceToFloor is greater than or equal to twice the hoverHeight or less than 0 (which should never happen but could possibly happen).
If you think about it like this if the distance to the floor is 10 and your hover height is 10 you should get a force of thrust - thrust/1^2 or thrust - thrust (0). If you get too close to the floor the thrust will increase more and more the closer you get. If you get far away the thrust will decrease since it can’t reach that far.
To determine the right force you can use something like this:
We know that in Roblox to get a zero gravity effect using force you’d apply a y force of workspace.Gravity*totalMass So our force can be twice this “anti gravity” force meaning at 20 studs (twice the hover height) you’ll achieve exactly workspace.Gravity*totalMass of force downwards (normal falling)
At 0 studs from the floor you’ll essentially be falling upwards.
The thrust value can be any value and it will determine the stability and speed of hovering. workspace.Gravity*totalMass is one times gravity. Since your dist/hoverHeight multiplier can reach 2 maximum (2^2 is 4) you need to at least divide the anti gravity force by 4 to make sure the hovercraft does not continue to bounce higher and higher. This doesn’t look all that smooth though so you can multiply this 1/4th gravity force by a decimal and play around with the results. 0.25 would be 25% this value for example.
Fun fact: This also works with multiple “thruster” parts and you can use BallJoints to connect them to the main body and BodyGyros to orient them upwards!
I explain that below (the second to last paragraph)
I also just noticed something there that I need to fix. Rather than two times the anti gravity force it can be any force since the antigravity force is added to the force equation already.
I am using raycasting to determine the distance to the floor and the angle of thrust. I can upload my place file with the hovering method I’m talking about. I’ve also updated my original post to include the fixed information.
My bad. It actually looks like the hovercraft in that video doesn’t use realistic thrusting. It looks like it’s simply using a BodyPosition and moving itself to the target height from the surface beneath. It also looks like it’s using a BodyGyro to rotate to the surface normal of the object directly beneath it. It looks like it may just be using the averages of the surface normals under the corners.
The target position should be the averaged surface normal times the target height. The target cframe is just a rotated cframe with the surface normal as the unrotated cframe’s look vector.
Use a BodyForce Thruster as your primary Force Thruster. Your system can then be modeled via state space as x_dot = Ax + Bu. State x is can be simplified as f=ma; thus yielding matrix A = {{0, 1}, {0, 0}} as velocity/acceleration are not dependent on state. B matrix is {{0}, {1/m}} due f/m = a.
With your state-space model, use LQR or Pole Placement to calculate gain matrix K. Gain matrix K can then be used in control law u = r-Kx. If you want, you can also implement a Kalman filter, but I think 20hz readings from your Raycasted position sensor should be suitable enough… Perhaps velocity measurement could be improved though as phase-locked velocity loops really suck.
Feed foward (u_final = u + mg) can be implemented without model consideration, as the model assumes the system has no external forces acting upon it. Even without feed foward, properly chosen gain matrix K should yield good reference tracking.