How could I make my raycast vehicles's physics smoother/allow change in weight?

Provide an overview of:

I’ll leave the project file and the raycast code below. Also, I’m sorry to drop this on the dev forum but I’m completely clueless as to what to do now.
Raycast Car.rbxl (33.0 KB)
*Edit - I cleaned up the place file

local RunService = game:GetService("RunService")

--stats
local Car = script.Parent
local carStats = Car.Stats


--Global Variables
local previousPosition = Vector3.new()

--Raycast Params
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {Car.Body,Car.mass}

for _, part in pairs(Car:GetChildren()) do
	if part.Name == "Thruster" or part.Name == "Thruster2" or part.Name == "Thruster3" or part.Name == "Thruster4" then
		local connection = RunService.Heartbeat:Connect(function(deltaTime)	
			
			local raycastResult = workspace:Raycast(part.Position, part.CFrame.LookVector * (carStats.Height.Value), raycastParams)
			raycastParams.FilterDescendantsInstances = {Car.mass,Car.Body}
			
			if raycastResult then
				local timestep = deltaTime
				local Force
				
				local function getPointVelocity(object, point)
					return object.Velocity + object.RotVelocity:Cross(point - object.Position)
				end
				
				local pointVelocity = getPointVelocity(Car.Body, part.Position)
				local suspDir = part.CFrame.LookVector
				
				previousPosition = Vector3.new(0,pointVelocity.Y,0)
				
				local RestLength = carStats.Height.Value --r
				local currentLength = part.Position.Y - raycastResult.Position.Y --p
				local displacement = currentLength-RestLength --x
				
				local mass = 800
				local dampingForce2 = mass/timestep
				local springForce2 = mass/(timestep^2)
				
				local Ck = tonumber(carStats.Ck.Value) --SpringForce
				local Cd = tonumber(carStats.Cd.Value) --DampingForce
				--f=-(m/t^2)*Ck*x -(m/t)*Cd*v
				local Force3 =  -springForce2*Ck*(displacement) -dampingForce2*Cd*(pointVelocity.Y)
				
				
				part.BodyThrust.Force = Vector3.new(0,0,Force3)
				
			else
				part.BodyThrust.Force = Vector3.new()
			end
		end)
	end	
end
1 Like

Okay, I managed to get the results I wanted. Unfortunately the method I used I forgot about the limitations of the spring which is that:

When connecting a multitude of springs and particles into larger bodies, we run into the same trouble as any other type of distance and velocity constraint. Rather than cooperating, the constraints tend compete against each other, and this spells trouble. When a spring moves two particles to satisfy distance and velocity, it usually means dissatisfying one or several other springs.

I had to switch my formula to a simpler one but I’m happier with the results. And to whoever is interested I made several changes. First off, I replaced the BodyThrusts with VectorForces because I realized the force needed to be applied to the hit point and not the side. Second, I switched the formula to F=(kx)+d(previouslength-currentlength)/deltatime.

local Force = stiffness * (RestLength - currentLength) + damping * (PreviousLengthTable[part.Name] - currentLength) / deltaTime

Finally for fixing the car being sent flying I set the network owner to the server. I will also leave the place file below for anyone who wants it.
Raycast Car.rbxl (33.2 KB)

5 Likes