Rigidbody+WheelCollider || Rigidbody+SphereCollider || Transform+Raycast

Hey guys. I’m currently working on a new version of my mobile game (so I can’t afford low physics time steps) and I’m trying to have a ball move along meshes. The meshes have mesh colliders as they are lofts. See attached image. I’m trying to get the sphere to move along the meshes. The sphere will be player-controlled with steering but will have automatic propulsion. So far, I’ve tried 3 systems (for the sphere) with no avail:

  1. Rigidbody + WheelCollider :-
    I attached a rigidbody and a wheel collider to the parent object (empty gameobject) of the sphere. Press play, the sphere drops onto the mesh, then falls through in a violent motion. What’s up with wheel colliders in Unity 5? It simply wont stay on the mesh even if I set timestep to 0.00002. Can’t a wheel collider just stand? I’ve also tried freeze z rotation on the rigidbody- with no avail.

  2. Rigidbody + SphereCollider :-
    The best system so far, but terrible in actuality. The sphere collider stays on the ground and moves, but it wiggles. This wiggling defeats its merits. I’ve tried freezing rotation and setting z rotation to zero (in every fixed update)- produces even more of an undesirable effect.

3.Transform + Raycast :-
My favorite option (because I dont like low timesteps). I’ve tried doing a raycast to the ground, setting the transform of the sphere to just above the raycast hit point (so it stays grounded) and using transform translate and rotate for propulsion and steering respectively. Unfortunately, the raycast seems to hate the edges of the mesh. When it gets near the edge of the mesh, I lose control of the sphere. The sphere starts to wiggle violently. Here is the raycast method:

if (Physics.Raycast (transform.localPosition, transform.TransformDirection (Vector3.down),out hit)) {
            transform.localPosition = hit.point + (hit.normal * Height);
            transform.rotation = Quaternion.LookRotation (transform.TransformDirection (Vector3.forward), hit.normal);
           
        }

        //Vector3 trans = transform.position;
        //trans.z += Input.GetAxis ("Vertical") * 2f;
        transform.Rotate (0, Input.GetAxis ("Horizontal"), 0);
        transform.Translate (0, 0, Input.GetAxis ("Vertical")*Time.deltaTime * 500f, Space.Self);
        Sphere.Rotate(0,0,Input.GetAxis("Vertical")*-4f);
        //transform.position = trans;

Please help me, and consider the transform method first as it would be the most efficient method. Thanks.

2075537--135497--Screen Shot 2015-04-19 at 3.01.50 PM.png

Physics.Raycast uses world coordinates in both origin and hit.point, but you are passing local coordinates. Also, the Transform class already exposes shortcuts for the transformed directions (no need for using TransformDirection here):

if (Physics.Raycast (transform.position, -transform.up), out hit)) {
            transform.position = hit.point + (hit.normal * Height);
            transform.rotation = Quaternion.LookRotation (transform.forward, hit.normal);
}

Edy, thanks for the reply. I’ve implemented your method, but the sphere goes through on the loop. I’m going back to 3ds max and increasing the loft segments; hopefully, this gives the mesh colliders more accuracy. Physics would have been most comfortable, but it’s too unpredictable. The sphere collider is terrible at this application.