Unity - Using a rigidbody for motorcycle - how do I turn?

2k views Asked by At

I'm new to Unity and rigidbodies, and I thought I'd learn by trying to make a 3D Tron Light-cycle game. I've made my player vehicle using a combination of cylinders, spheres, and rectangles, seen below:

enter image description here

I used a rigid body on the elongated sphere, and used the following code:

public float accel = 1.0f;    
// Use this for initialization
void Start () {
    cycleSphere = GetComponent<Rigidbody>();
}

void FixedUpdate () {
    cycleSphere.velocity = Vector3.forward * accel;
}

That moves the vehicle forwards. I'm not sure if there's a better way to do this, but if there is, please do say so.

I've attached the Main camera to the vehicle, and disabled X rotation to prevent it and the camera from rolling.

Now I would like to get it to turn by pressing the A and D buttons. Unlike the 90 degree turning of the original Tron light-cycles, I wanted it to turn like a regular vehicle.

So I tried this:

void Update () {
    if (Input.GetKey (KeyCode.A)) {
        turning = true;
        turnAnglePerFixedUpdate -= turnRateAngle;
    } else if (Input.GetKey (KeyCode.D)) {
        turning = true;
        turnAnglePerFixedUpdate += turnRateAngle;
    } else {
        turning = false;
    }
}

void FixedUpdate () {
    float mag = cycleSphere.velocity.magnitude;
    if (!turning) {
        Quaternion quat = Quaternion.AngleAxis (turnAnglePerFixedUpdate, transform.up);// * transform.rotation;
         cycleSphere.MoveRotation (quat);
    } 
    cycleSphere.velocity = Vector3.forward * accel;
}

While the above code does rotate the vehicle, it still moves in the last direction it was in - it behaves more like a tank turret. Worse, pressing either A or D too much would cause it to rotate in the desired direction and, after a short while, go nuts, rotating this way and that, taking the camera with it.

enter image description here

What did I do wrong and how can I fix it?

1

There are 1 answers

2
mrogal.ski On BEST ANSWER

First of all I would recommend you to change from Input.GetKey to Input.GetAxis which will gracefully increase or decrease it's value when the key is pressed. This will give you the option to normalize the force vector applied as your velocity. Then based on that vector you have to adapt your force input so that the "front wheel" will "drag" the rest of the body to some other direction ( left or right ). This is not the ideal "real world physics behavior" because the forward force is slightly bigger than the side ( left or right ) force.

code example :

// member fields 
float sideForceMultiplier = 1.0f;
float frontForceMultiplier = 2.0f;
Vector3 currentVeloticy = Vector3.zero;

void Update()
{
    Vector3 sideForce = (sideForceMultiplier * Input.GetAxis("horizontal")) * Vector3.right;
    Vector3 frontForce = frontForceMultiplier * Vector3.forward;
    currentVelocity = (sideForce + fronForce).Normalize;
}

void FxedUpdate()
{
    cycleSphere.velocity = currentVelocity * accel;
}