Making a car trailer!

Goal:

Create a trailer (not a video trailer) for a car that can reliably pull potentially heavy cargo.

Trailer attached to car with luggage in it.

Prerequisites:

Radical Relocation was created in Unity. At the time of writing, we were using version 2018.3.8f1.

Scripting runtime version is .NET 4x Equivilent and API Compatibility Level is .NET Standard 2.0.

This will not cover how to make a car script.

1. Aquire a trailer!

We use Blender to develop our 3D models. You will 2 components: the trailer, and separated wheels. It is important to ensure the wheels are not in the same mesh as the trailer in order to make them spin in Unity. Set the origin point of the trailer at the towball, and the origin point of the wheels in the center.

A render of a car trailer.

2. Import and Setup In Unity

Import your trailer into Unity. The hierarchy structure is important. Setup your trailer hierarchy as shown to the right.

Since this trailer will use a rigidbody, you will need to use a combination of cube colliders – a concave mesh collider is incompatible with rigidbodies.

To ensure your wheel colliders have the correct rotation, put your wheel colliders on a separate gameobject to the mesh. I recommend making the meshes child objects of the wheel colliders.

Trailer hierarchy structure

3. Components

The trailer root will need a rigidbody. Give it a realistic mass, say, 250kg.

Put a wheel collider on your designated empty objects. Here, configuration will not necessarily be realistic. A rule of thumb for wheel mass is 1/10th the mass of the rigidbody. In this case, approximately 25kg should work. Set the radius to match that of the mesh. Set the sideways friction stiffness to 3. This will help stop the trailer from swaying side to side. Leave all other values as default.

4. JOINTS

To make the trailer pivot from the towball, we will use a Configurable Joint. A Configurable Joint allows rotation on all axes. This is important – without it, your car will not be able to drive up a hill while pulling a trailer.

Assign the connected body; this will be the rigidbody on the car. Set the axis to (0, 1, 0) and the secondary axis to (0, 0, 1). Ensure the X, Y, Z motion is locked, and the angular X, Y, Z motion is limited.

Now we need to set limits for each axis. For the Y axis, it will depend on your model. In my case, I used -40 in the Low Angular X Limit, and 40 in the High Angular X Limit (I’m not sure why Unity labels this “X”). Set the Y and Z angular limit to 20 and 13 respectively.

The last thing to do is to ensure “Enable Collision” and “Enable Preprocessing” are unchecked.

Car trailer - configurable joint setup

5. Fake Motor

You may find that at this point, your vehicle is actually unable to move with the trailer attached. A simple solution is to provide some artificial motor torque to the trailer wheels. It will not affect the feel of the driving; it just needs to be enough to get the car rolling. This needs to happen for forward acceleration, and reversing.

 

[SerializeField] private WheelCollider[] m_WheelColliders;
[SerializeField] private float m_Torque = 10f;

private Rigidbody m_Rigidbody;
private bool m_IsReversing;

private void Start() => m_Rigidbody = GetComponent<Rigidbody>();

private void Update()
{
    // Convert from world space to local space. Anything less than zero in the forward direction is backwards.
    // Stationary will count as forwards.
    m_IsReversing = transform.InverseTransformDirection(m_Rigidbody.velocity).z < 0f;

    // Make it move!
    float input = Input.GetAxis("Vertical");
    float accel = Mathf.Clamp(input, 0f, 1f);
    float brake = Mathf.Clamp(-input, 0f, 1f);
    Throttle(accel);
}

private void Throttle(float accel, float brake)
{
    for (int i = 0; i < m_WheelColliders.Length; i++)
    {
        // Accelerator is applied
        if(accel > 0.0f)
        {
            if(m_IsReversing)
            {
                // When reversing, accelerator acts as a brake.
                m_WheelColliders[i].motorTorque = 0f;
            }
            else
            {
                // Apply a little bit of motor torque to help us get rolling
                m_WheelColliders[i].motorTorque = m_Torque;
                m_WheelColliders[i].brakeTorque = 0f;
            }
        }
        else if (brake > 0.0f)
        {
            if(m_IsReversing)
            {
                // The car is trying to reverse, give it some help.
                m_WheelColliders[i].motorTorque = -m_Torque;
                m_WheelColliders[i].brakeTorque = 0f;
            }
            else
            {
                // The car is braking!
                m_WheelColliders[i].motorTorque = 0f;
            }
        }
    }
}

Join the beta testing team!

We are rapidly approaching beta testing! If you would like to become a beta tester for Radical Relocation, sign up here and receive the final game on Steam for free!

Radical relocation car with luggage