Hello everyone. I’m working on a raycast vehicle suspension system, and there seems to be a problem which i have zero idea of how to solve. Basically, when there’s one vehicle inside of the game, it works perfectly fine. But when there’s multiple vehicles, the suspension starts going crazy. Any ideas as to why this could happen?
The server script:
local existingVehicles = {}
local vehTable = require(game.ReplicatedStorage.Vehicles)
local function addVehicle(veh)
if not existingVehicles[veh] then
table.insert(existingVehicles, veh)
veh:WaitForChild("Base"):SetNetworkOwner(nil)
existingVehicles[veh] = {}
existingVehicles[veh].wheelPositions = vehTable[veh.Name].wheelPositions
existingVehicles[veh].springLengths = vehTable[veh.Name].springLengths
existingVehicles[veh].properties = vehTable[veh.Name].properties
existingVehicles[veh].wheelSuspensionLengthMemory = vehTable[veh.Name].wheelSuspensionLengthMemory
end
end
for _, object in workspace:GetChildren() do
if object:HasTag("Vehicle") then
addVehicle(object)
end
end
while true do
local delta = game["Run Service"].Heartbeat:Wait()
for i, vehicle in ipairs(existingVehicles) do
local carModel = existingVehicles[i]
local car = carModel.PrimaryPart
local carCFrame = car.CFrame
local params = RaycastParams.new()
params.FilterDescendantsInstances = {carModel}
local wheelPositions = existingVehicles[vehicle].wheelPositions
local properties = existingVehicles[vehicle].properties
local stiffness = properties.stiffness
local damper = properties.damper
local springLenghts = existingVehicles[vehicle].springLengths
local wheelSuspensionLengthMemory = existingVehicles[vehicle].wheelSuspensionLengthMemory
local wheelRadius = properties.wheelRadius
local suspensionMaxLength = properties.suspensionMaxLength
for wheelName, pos in pairs(wheelPositions) do
local rayOrigin = carCFrame:ToWorldSpace(CFrame.new(pos)).Position
local rayDirection = -carCFrame.UpVector * (suspensionMaxLength + wheelRadius)
local raycast = workspace:Raycast(rayOrigin, rayDirection , params)
if raycast then
print("Ray Success")
local raycastDistance = (raycast.Position - rayOrigin).Magnitude
local springLength = math.clamp(raycastDistance - wheelRadius, 0, suspensionMaxLength)
local stiffnessForce = stiffness * (suspensionMaxLength - wheelSuspensionLengthMemory[wheelName])
local damperForce = damper * ((wheelSuspensionLengthMemory[wheelName] - springLength)/delta)
local suspensionForceVec3 = carCFrame.UpVector * (stiffnessForce + damperForce)
local RotationsOnlyWheelDirCFrame = CFrame.lookAt(Vector3.zero, carCFrame.LookVector, carCFrame.UpVector)
local LocalVelocity = RotationsOnlyWheelDirCFrame:ToObjectSpace(CFrame.new(car:GetVelocityAtPosition(raycast.Position)))
local Xforce = carCFrame.RightVector * -LocalVelocity.X * wheelRadius
wheelSuspensionLengthMemory[wheelName] = springLength
car:ApplyImpulseAtPosition(suspensionForceVec3 + Xforce, rayOrigin)
else
print("Ray Nil")
end
end
end
end
one vehicle:
multiple vehicles: