Smooth align Object with normal surface of ground

Dear all,

i just align a ridigbody (rotation freezed) with the ground. All works well with this code. I send ray to the ground and rotate the object with normal vector given by the hit on raycasting.

void FixedUpdate()
{
    RaycastHit hit;

    Vector3 theRay = transform.TransformDirection(Vector3.down); // Convert from local space to world space

    Debug.DrawRay(transform.position, theRay, Color.red);

    if (Physics.Raycast(transform.position, theRay, out hit)) 
    {
        transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
    }

}

However, the object doesn't align smoothly with the ground: rotation are rough. How i can do that?

Thanks for support,

Dragon

What is it supposed to do? Align with the ground directly under you? In that case, the problem is that your first line aims a ray at whatever angle your bottom faces. After the code tilts you that way, you are now aiming at a different section of the ground, so gets retilted next frame, and so on.

Try using just `theRay = Vector3.down;` Also a little odd that the ray is not a ray.

I also prefer just looking the normal up directly, on the assumption that a raycast is expensive, and does this lookup anyway:

// find normal under spot (C#):
TerrainData td = Terrain.activeTerrain.terrainData;
Vector3 grndNorm = td.GetInterpolatedNormal(spot.x/td.size.x, spot.z/td.size.z);

Instead of:
transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
Try:
transform.rotation = Quaternion.Slerp(transform.up, hit.normal, time);
where the time variable is usually:
time = Time.deltaTime * interpolateSpeed;

using UnityEngine;

public class SlopeDetectionScript : MonoBehaviour

{

RaycastHit hit;

Quaternion rot;

public int smooth;

void Update()

{

   Ray ray = new Ray(transform.position, -transform.up);
       
   if (Physics.Raycast(ray, out hit))
       
   {
            
         rot = Quaternion.FromToRotation(transform.up, hit.normal) * 
         transform.rotation;
            
         transform.rotation = Quaternion.Lerp(transform.rotation, rot, 
         Time.deltaTime * smooth);
       
   }

}

}