Why is my vehicle steering on its own when I accelerate?

My vehicle in Unity has a problem: it slightly steers on the right, on its own. And it's very strange, since all the WheelColliders are perfectly alligned and propelled with the same torque value. The only difference between the wheels is that rear wheels are bigger than front ones (my vehicle is a Kart), but they are perfectly mirrored. I tried to add some kind of hardcode correction, but I removed it because the problem persised, just behaving a bit differently. I hope it's not a bug... Anyway, I attached the code that moves the kart so you can check. Also, do you think this code is slow?


//CARATTERISTICHE DEL VEICOLO
/*Accelerazione*/ var maxtorque = 85.0;
/*Velocit*/ var maxspeed = 1.3;
/*Sterzata*/ var maxsteer = 15.0;
/*Frenata*/ var brakepower = 100.0;

//VALORI DI SISTEMA
/*Marcia iniziale*/ private var currentgear = 0;
/*Sterzata temporanea*/ private var tempsteer = 0.0;
/*Moltiplicatore sterzata*/ private var easysteer = 1.3;
/*Abbassa baricentro*/ rigidbody.centerOfMass = Vector3(0,-0.3,0);

//VALORI DI MOVIMENTO
/*Accelerazione finale*/   private var endTorque = 0.0;
/*Frenata finale*/   private var endBrake = 0.0;
/*Sterzata finale*/   private var endSteer = 0.0;

//DEFINISCI COLLIDER DELLE RUOTE
var Coll_FrSX = transform ;
var Coll_FrDX = transform ;
var Coll_ReSX = transform ;
var Coll_ReDX = transform ;

function FixedUpdate () {

//CAMBIA IL DRAG SE SI E' A TERRA O IN ARIA
if (Coll_ReDX.collider.isGrounded == true && Coll_ReSX.collider.isGrounded == true)
rigidbody.drag = 0.4;
if (Coll_ReDX.collider.isGrounded == false && Coll_ReSX.collider.isGrounded == false)
rigidbody.drag = 0.2;

//SISTEMA DEL CAMBIO
//Vai a folle
if (currentgear == 1 && Coll_ReDX.collider.rpm < 0.01 && Coll_ReDX.collider.rpm < 0.01) currentgear = 0;
if (currentgear == -1 && Coll_ReDX.collider.rpm > -0.01 && Coll_ReDX.collider.rpm > -0.01) currentgear = 0;
//Innesta la prima
if (currentgear == 0 && Input.GetAxis("Vertical") > 0.01) currentgear = 1;
//Innesta la retromarcia
if (currentgear == 0 && Input.GetAxis("Vertical") < -0.01) currentgear = -1;

//CAMBIA I VALORI DI MOVIMENTO IN BASE ALLA MARCIA
//Marcia avanti
if (currentgear == 1)
{
endTorque = Mathf.Clamp(Input.GetAxis("Vertical"),0.0,1.0)*maxtorque-((rigidbody.velocity.magnitude+rigidbody.velocity.magnitude)/maxspeed);
endBrake = Mathf.Clamp(Input.GetAxis("Vertical"),-1.0,0.0)*-brakepower;
endSteer = (tempsteer-(Mathf.Clamp((rigidbody.velocity.magnitude/easysteer)/2,0.0,tempsteer-1)))*(Input.GetAxis("Horizontal"));
}
//Marcia indietro
if (currentgear == -1)
{
endTorque = Mathf.Clamp(Input.GetAxis("Vertical"),-1.0,0.0)*60+(rigidbody.velocity.magnitude*7);
endBrake = Mathf.Clamp(Input.GetAxis("Vertical"),0.0,1.0)*brakepower;
endSteer = (tempsteer+10-(Mathf.Clamp(rigidbody.velocity.magnitude/easysteer,0.0,tempsteer-1)))*Input.GetAxis("Horizontal");
}

//Temporary code to be used before the Drifting code
Coll_ReDX.collider.sidewaysFriction.stiffness = 0.12;
Coll_ReSX.collider.sidewaysFriction.stiffness = 0.12;
Coll_FrDX.collider.sidewaysFriction.stiffness = 0.12;
Coll_FrSX.collider.sidewaysFriction.stiffness = 0.12;
tempsteer=maxsteer;

//MUOVI IL VEICOLO
//Accelerazione
Coll_ReDX.collider.motorTorque = endTorque;
Coll_ReSX.collider.motorTorque = endTorque;
//Frenata
Coll_ReDX.collider.brakeTorque = endBrake;
Coll_ReSX.collider.brakeTorque = endBrake;
//Sterzata
Coll_FrDX.collider.steerAngle = endSteer;
Coll_FrSX.collider.steerAngle = endSteer;

//ESCI DAL GIOCO
if (Input.GetKey ("escape")) {Application.Quit();}
}

//VISUALIZZA I DATI SU SCHERMO
function OnGUI(){
GUI.Label(Rect(0,0,1000,1000), "Speed: "+rigidbody.velocity.magnitude.ToString());
GUI.Label(Rect(0,20,1000,1000), "Air resistance: "+rigidbody.drag.ToString());
GUI.Label(Rect(0,40,1000,1000), "Gear: "+currentgear.ToString());
GUI.Label(Rect(0,60,1000,1000), "Render time: "+Time.deltaTime);
}

I've seen this crop up again and again, and unfortunately it does seem to be a bug with the way that wheelcolliders are implemented in the version of Physx which is included.

I haven't checked carefully through your code, but since I've seen people complain about this before, and I've seen it myself, I'm sure it's the bug.

I successfully made a few off-road type games where the bug wasn't apparent, but this was mainly because the terrain was quite rough and there were many bumps and jolts, so the slight pull to one side was not noticable, however it seems that the simple and cleaner your scene is, the more apparent the bug is. For example, a friend was making a forklift truck game - no suspension, no gears, and completely flat floors, and the bug was quite apparent. I think he gave up on wheelcolliders and switched to some other method of propulsion instead - as I have done with my latest car game (i.e. implemented my own wheel collider).

Let's hope this is one of the as-yet-unnamed "physics improvements" that are coming with Unity 3.

It's not exactly a bug - it's the way WheelColliders work. The sideways force generated by a wheel is based on the amount of sideways slip on that wheel. This means that some slip will always be present, even a small amount. If you raise the sideways stiffness to a ridiculously high value then the effect cannot be noticed, but you get infinite grip on that wheel.

Having the same issue, so far I have tracked it down to slight variation in the rpm on the drive wheels. Some vehicles drift right, some left, and some back and forth. I have tested the order of torque application, ect and it makes no difference.

This is a wild guess, but to me it seems to be an order of execution issue inside the engine where each is looped through (in what ever order the show up in the loop) and that time is used. Only the ultra minor difference being time is not the frame start time, but the current time. It could also be a precision issue, but I would expect to see it rear its head elsewhere if that were the case.

It seems in our case we are going to have to home grow a proper wheel.

I think it's probably because the centre of mass is not exactly in the centre. I know it's not because the wheels are rotating at different speeds because I had this problem with my bike sim and that only uses two wheels. The problem seems to have been fixed by moving the centre of gravity according to the angle of the bike.

I don't know how but the car of this guy goes straight.

http://forum.unity3d.com/viewtopic.php?t=52133

about the last reply: " I don't know how but the car of this guy goes straight. http://forum.unity3d.com/viewtopic.php?t=52133 "

this guy seemed to implement bumpy/rough track/terrain;it might be the reason

Maybe you could fix it with a constant force that would provide a torque on the front of the vehicle equal and opposite to how it is rotating.

Hi , I resolved problem by setting x of “centre of mass” gameObject with the sum of x wheelCollider left and x wheelCollider right , and then x of “centre of mass” gameObject = sum / 2 (to be exactly on centre) .