Smoothing Rigidbody movement over a bumpy track

I have a Rigidbody spaceship running on a very deformed race track (like a rollercoaster). The control happens only applying a force to the Rigidbody, so I don't use wheel-like controls. The ship runs sticked to the track by moving constantly down its local Y axis, just like being attracted by a magnet, while being affected by gravity if it jumps out of the road.

Since the track is quite bumpy in certain slopes and turnings, I easily lose the control of the vehicle, because it bumps too much... Is there any way to smooth the collision between the vehicle and the track?

Well first I'm going to mention "Rigidbody.interpolation" since this might sound like the obvious solution. You can switch this on, and it has the effect of smoothing out the movement of the physics object in question slightly, but in your case I don't think this is really going to help much, since it sounds like the bumps are at a larger scale, whereas this function is designed to smooth out the discrepencies which arise from the physics steps not being at an exactly steady rate.

I think perhaps what might be a better solution might be to split the "collision" and "visible" parts into two seprate pieces, and use a custom script to interpolate the visible object towards the collision object. I think you should have two GameObjects:

  1. Has rigidbody & collider, but no mesh renderer. This bumps over the track as you currently are doing, but is invisible.
  2. Has no rigidbody or collider. It just has the mesh renderer displaying the ship.

Let's call these gameobjects "Ship Physics" and "Ship Visible".

The 2nd object (Ship Visible) must not be parented to the first. Instead, it will follow the Ship Collider's movement by interpolating towards its position using this script. Create a new C# script, which should contain the following:

using UnityEngine;
using System.Collections;

public class InterpolateToTarget : MonoBehaviour {

    public Transform target;
    public float xInterpolation = 5;
    public float yInterpolation = 5;
    public float zInterpolation = 5;
    public float rotationInterpolation = 5;

    void Update () {
        Vector3 localPos = target.InverseTransformPoint(transform.position);
        localPos.x -= (localPos.x * xInterpolation * Time.deltaTime);
        localPos.y -= (localPos.y * yInterpolation * Time.deltaTime);
        localPos.z -= (localPos.z * zInterpolation * Time.deltaTime);
        transform.rotation = Quaternion.Slerp(transform.rotation, target.rotation, rotationInterpolation * Time.deltaTime);
        transform.position = target.TransformPoint(localPos);
    }
}

Place this script on the "Ship Visible" gameobject. Then (with "Ship Visible" still selected) drag a reference from the "Ship Physics" gameobject into the 'target' variable in the inspector.

Finally, you probably want to set it so that the interpolation along its own local Z axis is much faster than the others, since this is the forward direction of the ship, so change the value for "Z Interpolation" to somethin much higher, like 100.

Give it a try and see what happens. You might find that you want to tweak the settings to tighten or loosen the interpolation, but it should help smooth out the motion of the spaceship.

You should enable "Smooth Sphere Collisions" on the mesh collider component of your track. It smoothes the normals of the collision mesh.

Another try could be using different meshes for rendering and collision. The collision mesh should be as smooth as possible, but should contain geometry only in driveable areas.