Raycast vehicle movement

Trying to learn more about Raycast vehicle suspensions, shown below I have a snippet of code that just holds a part up using forces based on the Raycast, my question is how in the world do I even go about movement, turning etc? I can’t really find alot on it, everything seems to be about specifically holding the part up; I barely understand what i’m even doing here so my comments might even be wrong

CreateSuspension(delaTime)
	if globalPause then return end
	
	for name,attachment in pairs(chassis:GetChildren()) do
		if attachment.ClassName ~= "Attachment" then return end
		
		local springDirection : Vector3 = chassis.CFrame.UpVector
		local worldPosition : Vector3 = attachment.WorldPosition -- The attachments position relative to the world
		local vectorForce : VectorForce = attachment.VectorForce -- The force within the attachment
		
		local rayDirection : Vector3 = -chassis.CFrame.UpVector * (config.settings.springlength + config.settings.radius) -- Length of the raycast
		local raycastResult = workspace:Raycast(worldPosition, rayDirection) -- Raycasting
		
		if raycastResult then
			
			local worldVelocity  : Vector3 = chassis:GetVelocityAtPosition(worldPosition) -- The velocity attachment is travelling at
			local rayDistance : number = (worldPosition - raycastResult.Position).Magnitude -- The distance from the attachment to the ground (if within raydirection length)
			local offset : number = (config.settings.springlength - rayDistance) -- Subtract the ray distance from the ground to the spring length
			local velocity = worldVelocity:Dot(springDirection)
			
			local force : number = (offset * config.settings.strength) - (velocity * config.settings.damper) -- Calculate the force
			vectorForce.Force = (springDirection * force) -- Apply force to vector force instance
			
			
			--//What steps do I need to take to apply turning force / acceleration?
		end
	end
end
RunService.Heartbeat:Connect(CreateSuspension)```

I’m not a pro in this either, but I’ll try to help based on what I’ve messed with before.

To get movement working, you’d apply a force in the direction the chassis is facing using chassis.CFrame.LookVector, scaled by your input (like throttle). You can apply that with another VectorForce either directly on the chassis or on each suspension point depending on how you’re structuring it.

For turning you’d usually apply torque around the Y-axis of the chassis. That could be a Torque instance or by applying sideways forces in opposite directions on each side to simulate rotation. It’s a bit like twisting the chassis manually.

And if the vehicle slides too much, you’d want to handle grip by damping sideways velocity. Calculate how much the chassis is moving sideways (RightVector:Dot(velocity)) and apply a force to cancel some of that out.

It’s definitely more work than using built-in physics, but you get way more control.

Movement and turning are forces too, just applied differently. There are many great resources online, one of my favorite being this video explaining arcade vehicle physics quite well: https://www.youtube.com/watch?v=CdPYlj5uZeI
It shows code snippets made for the unity game engine, but the maths behind it all is still going to be about the same, whether you’re working on roblox or another engine.

A couple of tips that i can give you:

  • work with force instances, avoid :ApplyImpulse() - your code runs at a different rate/timestep than the roblox physics, so you’ll run into pretty bad issues with unstable physics at low framerates. Even with forces, this discrepancy between RunService.Heartbeat and the roblox physics solver can cause issues. The engine’s solver runs in iterations aka 2x / 4x more often than Heartbeat. These substeps help with physics precision, but aren’t great when you need to do precise physics maths yourself because your code is bound to miss any values and states between Heartbeat calls. I’ve seen issue with things like suspensions which would become incredibly bouncy at low framerates (<30fps). It’s not that common of a thing to run into, but you should know about it in case you ever do.
  • always take into account delta time - basic tip, but it’s something that you should just never forget. (of course, only use it where it’s needed).
  • don’t limit yourself to roblox. There are plenty of great resources online, but just because they aren’t directly made for roblox doesn’t mean they’re not useful. As long as the video/article/post goes into how everything works and the maths behind why it works, you can easily adapt that to any game engine.
1 Like

Thanks, replies proved helpful, though I’m left with one more question, For some reason the “vehicle” (which is just a part with raycast as of right now) seems to slide slightly to the right when rolling, why is this? Why does it not move straight?

You’re probably missing friction forces

So just to make sure I get this correctly;

Movement: Apply forward direction forces to the rear wheels
Friction: Forces in opposite directions
Turning: (Not entirely sure on this one, My best guess is rotate the attachments and then uhh, do something to make it turn (the vector forces are within each attachment))

Yeah! Mostly. One thing: you don’t rotate the attachments to turn. That’s not how steering is usually done in raycast vehicles. Apply opposing lateral forces or use steering angles in your raycast direction vectors to simulate wheel orientation. Rotating the attachments themselves won’t affect physics directly unless you’re changing how forces are applied.