Jailbreak Cars. I’ve been hearing a lot about them in the past few months and I’m really keen to get stuck into the mechanics of their suspension rig.
After doing my research, I have found out from numerous sources, that the rig uses Body Gyros & Body Thrusts in combination with ray-casting at each corner of the vehicle to acquire the force to push down on each wheel. This makes sense. The only part that doesn’t make sense is how this would relate to the servo movement of the wheels individually, allowing them to have their spring-like suspension; I could use a Spring Constraint but that defeats the purpose of the project.
I’m really keen to create my own version of the ‘Jailbreak Cars’ and I will be very much appreciative of all advice and examples posted.
The default Roblox jeep in the ‘Race’ and ‘City’ templates is a good starting point to show you how it works. I used the suspension code in that jeep as a base for this monstrosity: https://twitter.com/madattakRBLX/status/954397684319817728
It will require a fair bit of work for more advanced use, but it’s excellent as a starting point.
No problem! I forgot to add, for propulsion the default Roblox car script goes forwards and backwards by settings the velocity of the chassis rather than using a BodyThrust/Force - I wouldn’t recommend this as I’ve encountered bugs in the physics engine trying to use it.
Having connected the wheels with the chassis, your equation for the spring becomes,
This could be extended further but it’ll be enough for our dampened spring.
local d = 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 ST = {dx=0,d2x=0} --For storing the derivatives per suspension
while loop do --For every suspension, in this case 4 of them
local x = d - suspension_distance --X is how much the suspension is contracted
local f = a*x + b*(x-ST.dx) + b/2*(x-ST.d2x) --Use the equation
ST.d2x = ST.dx --Store the past values
ST.dx = x
Car.Force = Vector3.new(0,f,0) --Apply the forces
Wheel.Force = Vector3.new(0,-f,0)
end
It’s following Newton’s Second Law of Motion, applied Hooke’s Law.
An obvious way to look at it is that, you want the force acting on the system as decelerating. This isn’t the exact form for the damped spring and it doesn’t have integration applied to it.
For F=-k*x, we can put our acceleration and velocity dependent equations directly in negative form to show that the force is mostly (dependent on our constant) opposite to that of acceleration and velocity.
It would’ve taken too much time to write the force that’d need to be applied.
It says the second derivative in the formula but I’m actually using a 2*dt scale first derivative. This is to account for if the first derivation is not enough to slow it down, if it is, than 2*dt scale first derivative already equals to around 0.
If I wanted to do second derivative I’d need to change the script formula to
local f = a*x + b*(x-ST.dx) - b/2*(x-2*ST.dx+ST.d2x)
but that doesn’t work nicely. I didn’t actually mean to write second derivative to be honest. I was just lazy to show 2*dt in limit form.
I’m also trying to achieve a similar vehicle system. I fail to understand how to keep the wheels in place and move the main chassis up and down based on the wheel distance from the ground.
Don’t use the one made by Roblox. You identified the purpose of the project as not using spring constraints and creating the spring simulation via a script.
Edit:
You’re not supposed to be CFraming anything. You’re going to use 4 attachments and 4 force constraints for the chasis. You’re going to use an attachment and force constraint for each wheel and connect the chasis and wheels using something like prismatic constraint.
You’re supposed to simulate the force of suspension on script and apply it via force objects.
Ok… So what is it that you exactly want? Roblox’s example has a different approach to the equations than I do. UpdateThruster function in the LocalCarScript is the place where it does that.
--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)
but the one I suggested would have more realistic physics.