0
\$\begingroup\$

I have a driving game and use wheel colliders to control cars, but whatever I change with the WheelCollider components it doesn't get faster and is way too slow.

The code of the controller:

[System.Serializable]
public class AxleInfo
{
public WheelCollider leftWheel;
public WheelCollider rightWheel;
public bool motor;
public bool steering;
}

public class SimpleCarController : MonoBehaviour
{
public List<AxleInfo> axleInfos;
public float maxMotorTorque;
public float maxSteeringAngle;

// finds the corresponding visual wheel
// correctly applies the transform
public void ApplyLocalPositionToVisuals(WheelCollider collider)
{

    Transform visualWheel = collider.gameObject.transform;

    Vector3 position;
    Quaternion rotation;
    collider.GetWorldPose(out position, out rotation);

    visualWheel.transform.position = position;
    visualWheel.transform.rotation = rotation;
}

public void FixedUpdate()
{
    float motor = maxMotorTorque * Input.GetAxis("Vertical");
    float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

    foreach (AxleInfo axleInfo in axleInfos)
    {
        if (axleInfo.steering)
        {
            axleInfo.leftWheel.steerAngle = steering;
            axleInfo.rightWheel.steerAngle = steering;
        }

        if (axleInfo.motor)
        {
            axleInfo.leftWheel.motorTorque = motor;
            axleInfo.rightWheel.motorTorque = motor;
        }

        

        ApplyLocalPositionToVisuals(axleInfo.leftWheel);
        ApplyLocalPositionToVisuals(axleInfo.rightWheel);
    }
}
}

and here are the options of the WheelCollider (every wheel has the same options)...

From here I got the code by the way https://docs.unity3d.com/Manual/WheelColliderTutorial.html

\$\endgroup\$
1
\$\begingroup\$

Note my original response suggested simply increasing maxMotorTorque, but it appears this has no apparent effect by itself.

Try adding force to the parent (car_body) rigidbody along with the motor values of the wheel colliders. Something like this:

float motor = maxMotorTorque * Input.GetAxis("Vertical");
rb.AddForce(transform.forward * motor);
float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

You may need to lower the cg to get the car to handle the way you want.

slow car 400 torque fast car 40,000 torque

Here's the whole script, including tweaking the Center of Mass (with magic numbers here):

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;

[System.Serializable]
public class AxleInfo
{
    public WheelCollider leftWheel;
    public WheelCollider rightWheel;
    public bool motor;
    public bool steering;
}

public class CarController : MonoBehaviour
{
    public Text speedometer;

    public List<AxleInfo> axleInfos;
    public float maxMotorTorque;
    public float maxSteeringAngle;

    // finds the corresponding visual wheel
    // correctly applies the transform
    public void ApplyLocalPositionToVisuals(WheelCollider collider)
    {
        if (collider.transform.childCount == 0)
        {
            return;
        }

        Transform visualWheel = collider.transform.GetChild(0);

        Vector3 position;
        Quaternion rotation;
        collider.GetWorldPose(out position, out rotation);

        visualWheel.transform.position = position;
        visualWheel.transform.rotation = rotation;
    }

    Rigidbody rb;
    private void Start()
    {
        rb = GetComponent<Rigidbody>();
        rb.centerOfMass = new Vector3(0, -4, 0);
    }

    public void FixedUpdate()
    {
        float motor = maxMotorTorque * Input.GetAxis("Vertical");
        speedometer.text = string.Format("motor {0:N0}\n{1:N0} mph", motor, rb.velocity.magnitude);
        rb.AddForce(transform.forward * motor);
        float steering = maxSteeringAngle * Input.GetAxis("Horizontal");

        foreach (AxleInfo axleInfo in axleInfos)
        {
            if (axleInfo.steering)
            {
                axleInfo.leftWheel.steerAngle = steering;
                axleInfo.rightWheel.steerAngle = steering;
            }
            if (axleInfo.motor)
            {
                axleInfo.leftWheel.motorTorque = motor;
                axleInfo.rightWheel.motorTorque = motor;
            }
            ApplyLocalPositionToVisuals(axleInfo.leftWheel);
            ApplyLocalPositionToVisuals(axleInfo.rightWheel);
        }
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ I already tried that but it won't get faster. I think it has something to do with the new Physics engine unity has since v 5. \$\endgroup\$
    – DraftedDev
    Oct 10 at 15:11
  • \$\begingroup\$ You know what -- you are right! Will revise this answer with a solution. \$\endgroup\$ Oct 10 at 15:58
  • \$\begingroup\$ It finally worked. Thanks :) Also maybe use an extra speed variable instead of the motorTorque. \$\endgroup\$
    – DraftedDev
    Oct 10 at 16:32
  • \$\begingroup\$ Glad this helped. And yes, decoupling the force from the motorTorque seems like a good idea :-) \$\endgroup\$ Oct 10 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.