I have a car with only suspension which is handled by a script and VectorForce and it should be level and not move at all except when it goes over a bump.
The problem is that the car bounces around and it appears that the force generated gradually grows over time until it goes too high and the force is set back to 0 and falls back down where it repeats.
https://gyazo.com/fec6efc04e7aa4754f6ae48ffdacfc9e
Script:
-- // Services
local ReplicatedStorage, RunService = game:GetService("ReplicatedStorage"), game:GetService("RunService")
-- // Variables
local Car = script.Parent
local Wheels = {}
local MaxSuspensionLength = 4
local MaxSuspensionForce = 10000
local DampeningRatio = 0.99
local SuspensionLoopConnection = nil
-- // Functions
local function CreateWeld(Part0: BasePart, Part1: BasePart, Parent: Instance?)
local Weld = Instance.new("Weld")
Weld.Part0 = Part0
Weld.Part1 = Part1
Weld.Parent = Parent or Part0
end
local function CreateWheel(Attachment: Attachment): Part
local NewWheel = ReplicatedStorage:FindFirstChild("TemplateWheel"):Clone()
NewWheel.Parent = Car
NewWheel.Position = Attachment.WorldCFrame.Position
local VectorForce = Instance.new("VectorForce")
VectorForce.Parent = NewWheel
VectorForce.Attachment0 = Attachment
VectorForce.RelativeTo = Enum.ActuatorRelativeTo.World
return NewWheel
end
local function UpdateSuspension()
-- Loop trough all wheels
for index, wheel in pairs(Wheels) do
-- Get VectorForce object
local VectorForce: VectorForce = wheel["Wheel"].VectorForce
if not VectorForce.Attachment0 then return end
-- Get attachment
local Attachment: Attachment = VectorForce.Attachment0
-- Raycast
local Direction = -Attachment.WorldCFrame.UpVector * MaxSuspensionLength
local RayResult = workspace:Raycast(Attachment.WorldCFrame.Position, Direction)
-- If raycast found the thingymabob
if RayResult then
local RayInstance, DistanceToGround = RayResult.Instance, RayResult.Distance
-- If raycast instance is the baseplate (ground)
if RayInstance == workspace.Baseplate then
local SuspensionCompressionRatio = 1 - (DistanceToGround / MaxSuspensionLength)
local DesiredForce = SuspensionCompressionRatio * MaxSuspensionForce
local Force = DesiredForce + (wheel["LastForce"] - DesiredForce) * DampeningRatio
-- Make wheels stick to ground
wheel["Wheel"].Weld.C0 = Attachment.CFrame * CFrame.new(0, -DistanceToGround + wheel["Wheel"].Size.Y * 0.5, 0)
-- Apply force to wheel
VectorForce.Force = Vector3.new(0, Force, 0)
wheel["LastForce"] = Force
end
else
VectorForce.Force = Vector3.new(0, 0, 0)
--wheel["LastForce"] = 0
end
end
end
local function SetupCar()
for _, attachment: Attachment in pairs(Car.Chassis:GetChildren()) do
if attachment.Name == "WheelAttachment" then
local Wheel = CreateWheel(attachment)
Wheels[Wheel] = {Wheel = Wheel, LastForce = 0.5}
CreateWeld(Car.Chassis, Wheel, Wheel)
end
end
end
-- // Setup
SetupCar()
-- // Connections
SuspensionLoopConnection = RunService.Heartbeat:Connect(UpdateSuspension)
If you think you may have a solution or suggestion, please reply!