Hi, I finally understood why my car in unity can’t drift/powerslide like cars do in other racing games. Feel free to skip the boring part and only read the question down below if you know this issue.
problem:
Not realistic car grip/drift happens because tire slip value (from which the tire grip is evaluated) is separately measured for forward and sideways friction of wheel. That means when you are in a turn with RWD car and you give car more throttle, rear tires lose forward grip and start to slip forward but car won’t start to drift sideways like in reality because even though rear tires started slipping forward, sideways slip is still the same thus there will be no change on sideways friction curve and car will not lose any sideways grip. For this same reason cars with unity wheel colliders can’t do handbrake turns because rear wheels will start to slip forward but that only influences forward grip not sideways.
real tire physics:
From a physics standpoint it’s obviously not realistic because when tire starts to slip it goes from static friction where it sits on road to kinetic friction where it is doing lots of little jumps and this “jumping state” of kinetic friction affects tire grip in all directions not just forward or sideways separately.
my theoretical solution:
So the obvious solution would be that we can keep separated friction curves (because of different tire tread designs) but the slip value for these friction curves must be only one, evaluated as magnitude of vector2 of sideways and forward tire movement (slip). Unfortunately we can’t modify slip value only extremum, asymptote and stiffness of friction curve.
finally the question:
Is there something that I am missing with separated forward and sideways slips to make car drift realistically and if not, is there any workaround with friction curve parameters to fix this issue or can you suggest me some alternative wheel colliders which doesn’t have this issue?
I think it makes perfect sense to have two separate frictions. Take an exemple of a car being thrown sideways on ice. You would have side friction due to momentum, and forward friction if you start accelerating, result in two friction combining/competing to actually move the car. The same logic applies for any surface. You start drifting when the momentum of the car increase sideway drift, and your forward drift cannot compete anymore.
After I posted another a bit more simplified question regarding this issue https://answers.unity.com/questions/1762293/how-to-make-handbrake-turn-or-powerslide-with-whee.html?childToView=1762679#comment-1762679
It turns out that this really is one of few current wheel collider’s issues. Handbrake turning can easily be simulated with code that for example decreases rear wheel colliders sideways friction stiffness or extremum value (stiffness works better) when player uses handbrake. Throttle controlled power-slides are more complicated to accomplish with wheelcolliders, I tried to linearly decrease sideways stiffness or extremum value on rear wheels sideways friction curve when their forward spin exceeded extremum spin which helped but car was hard to control however if you have time for optimizing this kind of algorithm, you probably could make it work at some point. Another approach would be to apply a little side force on rear of the car to make it drift under specified circumstances. But if you really want to have fun and a realistic vehicle physics I highly suggest getting some vehicle physics system from unity asset store or alternative wheelcolliders from github.
I made a code that recudes the sideway stiffness by the forward slip, and the forward stiffness by the sideway slip. (it will overwrite the stiffness, you must add a stiffness multiplier to the code if you want to change the stiffness) Known issues: the car quickly slows down when drifting “analog” steering + drift and steering assist is highly recommended
//FIXED UPDATE
if (driftPhysics)//this bool is for testing porpuses only, normally it should be always true
{
foreach (AxleInfo axle in axles) // "AxleInfo" is class that stores 2 "Wheel"s
foreach (Wheel w in axle.wheels) //"Wheel" is a class that contains a wheelcollider and a gameobject that is responsible for the rendering
{
WheelHit wh;
if (w.coll.GetGroundHit(out wh))
{
WheelFrictionCurve side_ = w.coll.sidewaysFriction;
side_.stiffness = 1f - (Mathf.Abs(wh.forwardSlip) * w.coll.forwardFriction.stiffness);
w.coll.sidewaysFriction = side_;
WheelFrictionCurve forward_ = w.coll.forwardFriction;
forward_.stiffness = 1f - (Mathf.Abs(wh.sidewaysSlip) * w.coll.sidewaysFriction.stiffness);
w.coll.forwardFriction = forward_;
}
}
}