Issue trying to get accurate Quaternion.FromToRotation()

Hello!

I’m currently trying to get my character to smoothly rotate its transform.up to a normal vector from another object.

Doing the following in Update() works ‘fine’

Quaternion slopeRotation = Quaternion.FromToRotation(transform.up, RaycastSentToGrav.normal);
 
transform.rotation = Quaternion.Lerp(transform.rotation, slopeRotation * transform.rotation, 10f * Time.fixedDeltaTime);

*RaycastSentToGrav.normal is the normal of the object that im trying to rotate towards

This works except once im fully rotated (as in it wont go any further) it isn’t fully rotated

I found an ~.5 degrees inaccuracy in the final rotation for atleast 2 axis at a time

this wouldn’t be too bad but it really affects the character movement i have setup (aka the jumping eventually moves the character off the platform and the camera is ever so slightly tilted)

calculate your target rotation, get the angle between your current and the target, and if it’s less than some epsilon (lets say 1 degree?) just set it to the target rotation instead of lerping it.

Something like this:

var slopeRotation = Quaternion.FromToRotation(transform.up, RaycastSentToGrav.normal);
var targetRotation = slopeRotation * transform.rotation;
if(Quaternion.Angle(transform.rotation, targetRotation) < 1f)
    transform.rotation = targetRotation;
else
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, 10f * Time.fixedDeltaTime);

I solved it before i could read your response but the solution is similar:

This has to be done ONCE (when you find the normal of the surface) and it cant be a local variable (private quaternion slopeRotation/targetRotation:

slopeRotation = Quaternion.FromToRotation(transform.up, RaycastSentToGrav.normal);

targetRotation = slopeRotation * rb.rotation;

then in an update() put the actual applying:

rb.rotation = Quaternion.Lerp(rb.rotation, targetRotation, 8f * Time.deltaTime);

I changed transform.rotation to rb.rotation (not sure why but i need to test if that even made a difference)

turns out the inaccuracies were because it was always trying to get closer to a number that kept getting smaller to the point that debug and the inspector window couldn’t show the smaller numbers

This works near perfect and i tested with lerp, slerp, rotatetowards (take off time.deltatime if using rotatetowards) and they all produced the same END result of 8 sig figs of accuracy (90 → 90.000001)

the only issue im finding now is that the rotation is also affecting the rotation of my mouse, it always wants to ‘look’ in a certain direction which makes sense

i need to find a way to stop it from doing that, so if anyone has any tips please!