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?
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;
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);
}