I’m experimenting with 3D automotive physics in Unity and need a good automotive for a racing sport.
I have been attempting to implement turning (and drifting) for this automotive. I need the automotive to robotically drift at excessive speeds with out the consumer needing to press an additional key. Nonetheless, it doesn’t matter what I do, the automotive at all times does one among two issues when turning: it both flips over when turning at excessive speeds (with out drifting) or spins round uncontrollably till the automotive is going through away from its velocity, i.e. the slip angle is 180 levels. (when drifting).
I’ve checked out these two tutorials (primarily) for assist: https://www.youtube.com/watch?v=CdPYlj5uZeI and https://www.asawicki.data/Mirror/Carpercent20Physicspercent20forpercent20Games/Carpercent20Physicspercent20forpercent20Games.html.
What I need is a automotive that turns usually at low speeds and drifts at a constant and visual slip angle at excessive speeds. Maybe one thing much like Asphalt 8.
Listed here are some particulars about my automotive’s implementation. (The code is just too jumbled up to have the ability to present you immediately, however let me know in case you want the code)
-
I’ve a single Rigidbody and BoxCollider for the automotive. It weighs 1439 kg and is 4 m lengthy x 1 m excessive x 2 m extensive. The automotive’s prime pace is 300 km/h.
-
I’m not utilizing
WheelColliders
. The wheels are simulated and applied utilizing forces on the rigidbody. Every wheel has its personal GameObject. This GameObject sends a raycast all the way down to the bottom to trace the place the wheel contacts the bottom. If the gap is bigger than about 1 m, the wheel is registered as not touching the bottom. Every wheel has a script,Wheel.cs
, that applies the next forces on the rigidbody at this contact level:-
Suspension: I take advantage of a suspension pressure of 30000 N/m and a damping pressure of 4000 N/(m/s).
-
Acceleration / Braking: I take advantage of a rear-wheel drive. The pressure utilized on the contact level is a operate of the longitudinal velocity of the automotive and is decided by an
AnimationCurve
. It begins at 14000 N at resting place, peaks at 21000 N at 120-210 km/h (which I do know is unrealistic due to most traction pressure), and lowers to 15000 N at 300 km/h. The output from this curve is split by the variety of driving (rear) wheels that contact the bottom, and this pressure is solely utilized to the wheels that contact the bottom. -
Turning / Slide discount: Turning is applied by decreasing or eliminating the lateral velocity of every wheel. The entrance wheels are liable for turning. I take advantage of Ackermann steering if that is related. When the A or D key’s pressed, the wheels flip 12-14 levels relative to the automotive’s route.
The grip for every wheel determines the fraction of lateral velocity that’s eradicated every physics tick. That is primarily based on an
AnimationCurve
, and is a operate of the slip angle (it is truly the sine of the slip angle). The grip will get smaller and smaller the extra the wheel strikes sideways.I may multiply the lateral pressure of the rear wheels by some fixed (between 0 and 1) if I believe the pressure is an excessive amount of (drifting implementation). The precise code I take advantage of for that is
float sidewaysVelocity = Vector3.Dot(rb.GetPointVelocity(hit.level), remodel.proper); // Lateral velocity float totalVelocity = Vector3.Scale(rb.GetPointVelocity(hit.level), remodel.ahead + remodel.proper).magnitude; // Complete velocity float sidewaysVelocityRatio = totalVelocity == 0 ? 0 : Mathf.Abs(sidewaysVelocity) / totalVelocity; // Discover sideways velocity ratio. Vector3 lateralAccel = -sidewaysGrip.Consider(Mathf.Clamp01(sidewaysVelocityRatio)) * sidewaysVelocity * remodel.proper / Time.fixedDeltaTime; // Acceleration to appropriate the sideways velocity bool isDrifting = Vector3.Dot(lateralAccel, remodel.proper) > maxLateralForce; // Examine if wheel ought to drift. (I've maxLateralForce set to 14000 N, roughly the automotive's weight) if(isDrifting && isRearWheel) { // Make the rear wheels drift lateralAccel *= Mathf.Lerp(1f, automotive.driftGrip, Mathf.Abs(Enter.GetAxis("Horizontal"))); } // automotive.driftGrip is about to 0.6 proper now. I've examined values from 0.2 to 0.95. rb.AddForceAtPosition(lateralAccel, hit.level);
-
Rolling resistance: Takes the wheel’s longitudinal pace, multiplies it by a coefficient, and sends a pressure the alternative manner. I’ve used a rolling resistance of 10.5 N/(m/s) for every wheel, so it totals as much as 42 N/(m/s).
-
-
The rigidbody’s COM is about to (0, -0.6, 0).
-
Drag can be applied. It is in the wrong way of the automotive’s velocity and proportional to the sq. of the automotive’s pace. I’ve used a drag coefficient of 1.4 N/((m/s)^2).
The problem appears to be within the slide discount: If I flip at excessive speeds (above 80 km/h), the lateral pressure is an excessive amount of and the automotive flips. After I add the drifting code, the automotive spins uncontrollably at excessive speeds. If I apply any type of countersteering (pressure or torque or immediately altering the steering angle, attempting completely different quantities of countersteering, making use of it on completely different wheels), it’s both ineffective or the automotive finally ends up flipping once more. I assumed it made sense to lower the entrance wheels’ grip barely as effectively for drifting, but it surely did not work.
What could also be a purpose for this behaviour, and the way can I repair this?
I apologize if there are particulars concerning the automotive that I ought to’ve offered, or if I confused you. Additionally, I do know lots of this info is irrelevant, however I added it simply in case.