Hi All,
I am trying to make a raycasting suspension system for a car.
After seeing this video, I decided to give raycast suspension a try because it suits my needs - Space Dust Racing UE4 Arcade Vehicle Physics Tour - YouTube
In my initial attempt at creating the raycast suspension, the “vehicle” (currently just a part) does float but it rocks (tilts & slides) back and forth.
After some further searching, I found this link where Oseday shares his suspension mathematics - Car Suspension (Scripted) - #5 by Kampfkarren
Unfortunately, I don’t really understand the math. I tried my best to implement it, but it still doesn’t balance and bounces up and down.
All assistance is appreciated, thanks in advance.
local d = 1 -- Suspension length?
local a = 1.8 --Stiffness, higher means higher height at suspension
local b = 0.6 --Rigidity higher means the suspensions will get less effected by slight changes and will balance out unlike Roblox's suspensions. This is the part that dampens the suspension.
local RunService = game:GetService("RunService")
local ST = {dx=0,d2x=0} --For storing the derivatives per suspension
local body = script.Parent
-- Initialise suspension force
local backLeftBodyThrust = Instance.new("BodyThrust")
backLeftBodyThrust.Name = "BackLeftBodyThrust"
backLeftBodyThrust.Location = Vector3.new(body.size.X/2, body.size.Y/2, body.size.Z/2)
backLeftBodyThrust.Parent = body
local backRightBodyThrust = Instance.new("BodyThrust")
backRightBodyThrust.Name = "BackRightBodyThrust"
backRightBodyThrust.Location = Vector3.new(-body.size.X/2, body.size.Y/2, body.size.Z/2)
backRightBodyThrust.Parent = body
local frontLeftBodyThrust = Instance.new("BodyThrust")
frontLeftBodyThrust.Name = "FrontLeftBodyThrust"
frontLeftBodyThrust.Location = Vector3.new(body.size.X/2, body.size.Y/2, -body.size.Z/2)
frontLeftBodyThrust.Parent = body
local frontRightBodyThrust = Instance.new("BodyThrust")
frontRightBodyThrust.Name = "FrontRightBodyThrust"
frontRightBodyThrust.Location = Vector3.new(-body.size.X/2, body.size.Y/2, -body.size.Z/2)
frontRightBodyThrust.Parent = body
RunService.Heartbeat:Connect(function()
local corners = {
backLeftCorner = body.Position - Vector3.new(body.size.X/2, 0, body.size.Z/2),
backRightCorner = body.Position - Vector3.new(-body.size.X/2, 0, body.size.Z/2),
frontLeftCorner = body.Position - Vector3.new(body.size.X/2, 0, -body.size.Z/2),
frontRightCorner = body.Position - Vector3.new(-body.size.X/2, 0, -body.size.Z/2),
}
local forces = {
}
for i, corner in pairs(corners) do
local rayOrigin = corner
local rayDirection = Vector3.new(0,-100,0)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {body}
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
local x
if raycastResult then
x = d-(corner - raycastResult.Position).Magnitude
local f = (a*x + b*(x-ST.dx) + b/2*(x-ST.d2x)) * body.Mass/2 --Use the equation
ST.d2x = ST.dx --Store the past values
ST.dx = x
table.insert(forces, Vector3.new(0,f,0))
--Wheel.Force = Vector3.new(0,-f,0)
end
end
print(forces)
backLeftBodyThrust.Force = forces[1]
backRightBodyThrust.Force = forces[2]
frontLeftBodyThrust.Force = forces[3]
frontRightBodyThrust.Force = forces[4]
end)