We have a vehicle we need ground-clamped. We can’t use Unity’s physics on it because it occasionally gets corrected from a simulation outside of Unity. The vehicle’s towing something that is controlled by physics, so we need the Rigidbody.
In FixedUpdate, we move the vehicle along its forward vector (for us, transform.right, because of the way its modeled) using the Rigidbody.MovePosition:
var deltaPos = m_tractorBody.transform.right * speed * Time.deltaTime;
var tractorPos = PutOnGround(m_tractorBody.position + deltaPos);
tractorPos.y += m_tractorHeightAboveGround;
m_tractorBody.MovePosition(tractorPos);
The PutOnGround method returns a Vector3 at the same x,z position as the input vector, with y set to the ground height at that x,z. I’ve trid sampling ground height both by casting rays and using GetInterpolatedHeight.
After that, we get a normal based on the terrain. I’ve tried both using the terrain normal, and sampling terrain height at three points around the vehicle, and using the normal of the plane constructed from those 3 ground points. To orient the vehicle to the ground, and then face it in the right direction, I do this:
var deltaHeading = heading - m_heading;
var deltaOrientation = Quaternion.AngleAxis(deltaHeading, Vector3.up);
// Now, get terrain normal, either by the plane or //GetInterpolatedNormal (code not shown) call it tractorNormal
Quaternion newOrientation =
Quaternion.FromToRotation(m_tractorBody.transform.up,
tractorNormal);
var angle = Vector3.Angle(m_tractorBody.transform.up, tractorNormal);
var totalTime = angle / m_angularVelocityDegPerSecond;
//Now, orient the tractor to that normal.
m_tractorBody.MoveRotation( m_tractorBody.rotation
* deltaOrientation
* newOrientation);
This works fine, when it works, but other times the vehicle starts shaking violently. It seems to happen on certain places on the terrain, but I can’t see what’s different about those places. Our terrain is fairly smooth, rolling hills with a banked road. Oddly, it seems to take the banked road pretty well, but some of the rolling hills on the terrain make it shake violently or start flipping.
I’ve tried all the Rigidbody interpolation settings, without any affet. The vehicle was behing followed by a camera using SmoothLookAt. I changed its update to FixedUpdate, no effect.
I’ve tried alleviating the problem by Slerping toward the new normal, rather than just popping to it, but eventually there’s a violent shake or pop that messes that up, leaving the vehicle at an odd angle. I’ve also tried averaging past and predicted normal (based on direction vehicle’s heading). It alleviated the problem somewhat, but occasionally I got the violent shaking.
I’m still using Unity 3.5.7. If anybody has an idea of what causes this and how to fix it, I’d appreciate it!