So i have been scripting raycast hover cars and i ran into this weird problem
local Thusters = SuspensionCar.Thusters:GetChildren()
local Hitbox = SuspensionCar.Hitbox
local Force = Hitbox.BodyForce
local DamperHeight = 10
local Multipler = 0.01
local Weight = 0
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterDescendantsInstances = {SuspensionCar}
RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
local Suspension = function()
local Direction = Vector3.new(0, -1000, 0)
local Raycast = workspace:Raycast(Hitbox.Position, Direction, RaycastParameters)
if Raycast and Raycast.Instance.CanCollide then
print(Raycast.Instance)
local DistanceFromGround = (Hitbox.Position - Raycast.Position).Magnitude
local PushUp = 1 + (DamperHeight - DistanceFromGround) * Multipler
Force.Force = Vector3.new(0, Hitbox:GetMass() * workspace.Gravity * PushUp, 0)
else
Force.Force = Vector3.new(0,0,0)
end
end
local updateSuspension = coroutine.wrap(function()
while wait() do
Suspension()
end
end)
updateSuspension()```
There are two problems that are causing this: first, because there is only a goal height and not a range of tolerance, the controller is always trying to compensate, resulting in oscillation. Second, even if there is a range of tolerance that the vehicle’s height can be, setting the force exactly equal the force of gravity on the vehicle does nothing to stop the inertia of the forces required to correct the vehicle’s position.
I’m not well-versed in physics, so this modified code will require some tweaking, particularly in regards to creating the force against inertia once the vehicle is already in range, but this should at least convey the idea of what needs to be done.
local Thusters = SuspensionCar.Thusters:GetChildren()
local Hitbox = SuspensionCar.Hitbox
local Force = Hitbox.BodyForce
local DamperHeight = 10
local HeightRange = 2 --Distance from DamperHeight that will be tolerated.
local Multipler = 0.01
local Weight = 0
local RaycastParameters = RaycastParams.new()
RaycastParameters.FilterDescendantsInstances = {SuspensionCar}
RaycastParameters.FilterType = Enum.RaycastFilterType.Blacklist
local Suspension = function()
local Direction = Vector3.new(0, -1000, 0)
local Raycast = workspace:Raycast(Hitbox.Position, Direction, RaycastParameters)
if Raycast and Raycast.Instance.CanCollide then
print(Raycast.Instance)
local DistanceFromGround = (Hitbox.Position - Raycast.Position).Magnitude
local PushUp
local HeightDifference = DamperHeight - DistanceFromGround
local AbsoluteDifference = math.abs(HeightDifference)
if math.abs(HeightDifference) < HeightRange then
--Vehicle is within tolerance. Current velocity needs to be canceled out.
PushUp = 1 - (Hitbox.AssemblyLinearVelocity.Y * Multipler)
else
--Vehicle is out of tolerance. Forces must be applied to return to within tolerance.
PushUp = 1 + (math.abs(AbsoluteDifference - HeightRange) * math.sign(HeightDifference) * Multipler)
end
Force.Force = Vector3.new(0, Hitbox:GetMass() * workspace.Gravity * PushUp, 0)
else
Force.Force = Vector3.new(0,0,0)
end
end
local updateSuspension = coroutine.wrap(function()
while wait() do
Suspension()
end
end)
updateSuspension()
I guess I should say as an aside: the height tolerance is perhaps unnecessary. The crux of solving the problem is compensating for both deviation in height and velocity. This could theoretically be done simultaneously to achieve a precise float height.