Jeep Suspension Issue

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want the jeep to have proper stability and not falling everywhere
  2. What is the issue? Include screenshots / videos if possible!
    A huge massive issue in Roblox, is an issue with raycast,and physics. when the player is on a low fps Therefore, causing the Jeep to have abnormal behaviour such as bouncing, and fling.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I"ve tried all that I could find on the internet but this didn’t work.
    After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!
    To look more to what I’m look for there’s many models but here’s the main model
--Scripted by DermonDarble
local userInputService = game:GetService("UserInputService")
local camera = game.Workspace.CurrentCamera
local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character.HumanoidRootPart
local car = script:WaitForChild("Car").Value
local stats = car:WaitForChild("Configurations")
local Raycast = require(car.CarScript.RaycastModule)

local cameraType = Enum.CameraType.Follow

local movement = Vector2.new()

local seat = car:WaitForChild("DriveSeat")

seat.Changed:Connect(function(property)
	if property == "Throttle" then
		movement = Vector2.new(movement.X, seat.Throttle)
	end
	if property == "Steer" then
		movement = Vector2.new(seat.Steer, movement.Y)
	end
end)

local force = 0
local damping = 0

local mass = 0

for i, v in pairs(car:GetChildren()) do
	if v:IsA("BasePart") then
		mass = mass + (v:GetMass() * 196.2)
	end
end

force = mass * stats.Suspension.Value
damping = force / stats.Bounce.Value

local bodyVelocity = Instance.new("BodyVelocity", car.Chassis)
bodyVelocity.velocity = Vector3.new(0, 0, 0)
bodyVelocity.maxForce = Vector3.new(0, 0, 0)

local bodyAngularVelocity = Instance.new("BodyAngularVelocity", car.Chassis)
bodyAngularVelocity.angularvelocity = Vector3.new(0, 0, 0)
bodyAngularVelocity.maxTorque = Vector3.new(0, 0, 0)

local rotation = 0

local function UpdateThruster(thruster)
	--Make sure we have a bodythrust to move the wheel
	local bodyThrust = thruster:FindFirstChild("BodyThrust")
	if not bodyThrust then
		bodyThrust = Instance.new("BodyThrust", thruster)
	end
	--Do some raycasting to get the height of the wheel
	local hit, position = Raycast.new(thruster.Position, thruster.CFrame:vectorToWorldSpace(Vector3.new(0, -1, 0)) * stats.Height.Value)
	local thrusterHeight = (position - thruster.Position).magnitude
	if hit and hit.CanCollide then
		--If we're on the ground, apply some forces to push the wheel up
		bodyThrust.force = Vector3.new(0, ((stats.Height.Value - thrusterHeight)^2) * (force / stats.Height.Value^2), 0)
		local thrusterDamping = thruster.CFrame:toObjectSpace(CFrame.new(thruster.Velocity + thruster.Position)).p * damping
		bodyThrust.force = bodyThrust.force - Vector3.new(0, thrusterDamping.Y, 0)
	else
		bodyThrust.force = Vector3.new(0, 0, 0)
	end
	
	--Wheels
	local wheelWeld = thruster:FindFirstChild("WheelWeld")
	if wheelWeld then
		wheelWeld.C0 = CFrame.new(0, -math.min(thrusterHeight, stats.Height.Value * 0.8) + (wheelWeld.Part1.Size.Y / 2), 0)
		-- Wheel turning
		local offset = car.Chassis.CFrame:inverse() * thruster.CFrame
		local speed = car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity)
		if offset.Z < 0 then
			local direction = 1
			if speed.Z > 0 then
				direction = -1
			end
			wheelWeld.C0 = wheelWeld.C0 * CFrame.Angles(0, (car.Chassis.RotVelocity.Y / 2) * direction, 0)
		end
		wheelWeld.C0 = wheelWeld.C0 * CFrame.Angles(rotation, 0, 0)
	end
end

--A simple function to check if the car is grounded
local function IsGrounded()
	local hit, position = Raycast.new((car.Chassis.CFrame * CFrame.new(0, 0, (car.Chassis.Size.Z / 2) - 1)).p, car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(0, -1, 0)) * (stats.Height.Value + 0.2))
	if hit and hit.CanCollide then
		return(true)
	end
	return(false)
end

local oldCameraType = camera.CameraType
camera.CameraType = cameraType

spawn(function()
	while character.Humanoid.SeatPart == car.DriveSeat do
		game:GetService("RunService").RenderStepped:wait()
		
		--Broken gyro input
		--[[if userInputService.GyroscopeEnabled then
			local inputObject, cframe = userInputService:GetDeviceRotation()
			local up = cframe:vectorToWorldSpace(Vector3.new(0, 1, 0))
			local angle = (1 - up.Y) * (math.abs(up.X) / up.X)
			movement = Vector2.new(angle, movement.Y)
		end]]
		
		if IsGrounded() then
			if movement.Y ~= 0 then
				local velocity = car.Chassis.CFrame.lookVector * movement.Y * stats.Speed.Value
				car.Chassis.Velocity = car.Chassis.Velocity:Lerp(velocity, 0.1)
				bodyVelocity.maxForce = Vector3.new(0, 0, 0)
			else
				bodyVelocity.maxForce = Vector3.new(mass / 2, mass / 4, mass / 2)
			end
			local rotVelocity = car.Chassis.CFrame:vectorToWorldSpace(Vector3.new(movement.Y * stats.Speed.Value / 50, 0, -car.Chassis.RotVelocity.Y * 5 * movement.Y))
			local speed = -car.Chassis.CFrame:vectorToObjectSpace(car.Chassis.Velocity).unit.Z
			rotation = rotation + math.rad((-stats.Speed.Value / 5) * movement.Y)
			if math.abs(speed) > 0.1 then
				rotVelocity = rotVelocity + car.Chassis.CFrame:vectorToWorldSpace((Vector3.new(0, -movement.X * speed * stats.TurnSpeed.Value, 0)))
				bodyAngularVelocity.maxTorque = Vector3.new(0, 0, 0)
			else
				bodyAngularVelocity.maxTorque = Vector3.new(mass / 4, mass / 2, mass / 4)
			end
			car.Chassis.RotVelocity = car.Chassis.RotVelocity:Lerp(rotVelocity, 0.1)
			
			--bodyVelocity.maxForce = Vector3.new(mass / 3, mass / 6, mass / 3)
			--bodyAngularVelocity.maxTorque = Vector3.new(mass / 6, mass / 3, mass / 6)
		else
			bodyVelocity.maxForce = Vector3.new(0, 0, 0)
			bodyAngularVelocity.maxTorque = Vector3.new(0, 0, 0)
		end
		
		for i, part in pairs(car:GetChildren()) do
			if part.Name == "Thruster" then
				UpdateThruster(part)
			end
		end
	end
	for i, v in pairs(car:GetChildren()) do
		if v:FindFirstChild("BodyThrust") then
			v.BodyThrust:Destroy()
		end
	end
	bodyVelocity:Destroy()
	bodyAngularVelocity:Destroy()
	camera.CameraType = oldCameraType
	userInputService.ModalEnabled = false
	script:Destroy()
end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

1 Like

You may want to use…

local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild(ā€œHumanoidRootPartā€)

On the og script changing * 196.2 to 296.2 (just adding more mass weight) seemed to help.

this is about physics
it’s the thrusters that are making them bug out

Would VectorForce work better than the deprecated BodyForce?
There are more properties that you can fine tune.

1 Like

nope? I’ve tried that before, somehow never works.

You have to experiment with the settings to get it working correctly. The documentation on it only gives you info, not reasoning or examples.
There was a Roblox test place for the Constraint forces. I don’t know if it’s still active. It basically had Parts with forces in them with different settings that would stay at different orientations or positions depending on Attachment or world or axis settings.

You could try setting network ownership to the server: Network ownership | Documentation - Roblox Creator Hub
I think the issue is that the network ownership is a client that’s really laggy and it’s causing all the physics bugs. Assuming the server has a way more stable and high fps, it may fix the issue.
(Though, I think when the player sits in the car, it will automatically set the ownership back to the player, so it may have 0 effect whatsoever, though you could always make some system that makes it so they player is never actually connected to the car so never gets ownership)

What type of settings do you mean

The properties of the VectorForce are explained at the link provided as well as the class desription here.

These properties are all related to one another. If you don’t have the proper Attachment configuration, or enough Force, or the RelativeTo property is set incorrectly then of course you’ll have issues.
Experiment with different combinations of the properties to learn how they interact. Later tonight I’ll send a link to the tutorial place I mentioned before.

so if in low fps should it have less force or more?

look it’s about the thrsuter and delta time this is a local script but I don’t know how to implant the dt/60 properly, well it worked but the thrusters were all the way down which I don’t want

Not easily possible

Why is the force changing to 0 though?

I think if you get rid of the

else 
    bodyThrust.force = Vector3.new(0,0,0) 

line you shouldn’t have an issue.

The only reason you’d want this to be 0 is if the car is Anchored or at the top of the suspension travel.
If the car is driving, or at rest, then there should be some force applied. If you zero it out every frame of course the car will drop if your frame rate is lower.

Here’s the tutorial place. It was open sourced and I’m pretty sure I renamed my version because the original had a difficult to search title.
It’s a bit more of an explanation of each style of the ā€˜new’ constraint movers.
New Body Movers, Physics, Constraints Example.rbxl (35.0 KB)
You can’t really play in it with your player, but if you use Run for testing you can move the parts with the Studio tools.

it’s changing to 0 cause It’s not on ground

look grab a jeep model from the link I pre-sent and get a render plugin set your fps cap to the lowest
and you’ll see what I mean

see if you could fix it then you’ll see.

How come one person can fix it then?

Here’s what I see in the UpdateThruster function:
It’s looking at the raycast and seeing if the raycast is at the right position.
If it’s ā€œon the groundā€ then it provides a force upward.
If it’s not ā€œon the groundā€ which could mean it’s just .001 stud off the ground then make the force 0.
So if the height isn’t on the ground there seems to be no force holding the car up. A lower fps means it won’t be updating every frame and will cause issues.
My thinking is that if you think of a real car with springs the springs aren’t active just when they are at the minimum height. They are supporting the car’s weight all of the time. If you turned the springs on and off like your script the car would almost always be sitting at their minimum height.
Sounds like you should be doing a check on the actual length of the raycast.

  • If it’s at the minimum height (ā€œon the groundā€ so let’s say 0 studs) then make the force the calculated value you have in the script.
  • If the height is at the maximum height (let’s say 2 studs) then have the force at 0.
  • Use a percentage between the 2 heights for all the other force calculations, so if the height is at .329 studs the force would be 0.658 of the force required at 0 studs, like a spring would be.

look see for yourself try do that and that won’t fix anything