transform.localRotation lerp precision

Hello,

I’ve got a method which is responsible for lerping rotation using steps, each step is 5% of rotation distance:

    IEnumerator Test()
    {
        int steps = 0;
        for (int i = 0; i < 20; i++)
        {
            float stepValue = currentPosition.localRotation.y - leftTileTarget.localRotation.y * .05f;
            //print("1. stepValue: " + stepValue);
            //print("2. local rotation value: " + transform.localRotation.y);
            float newRotationValue = Mathf.Abs(transform.localRotation.y) + stepValue;
            //print("3. new rotation value: " + newRotationValue);
            float step = newRotationValue / Mathf.Abs(leftTileTarget.localRotation.y);
            print("4. step " + step);
            // TODO how to avoid changing decimal points value
            transform.localRotation = Quaternion.Lerp(currentPosition.localRotation, leftTileTarget.localRotation, step);
            //print("5. local rotation y after lerp: " + transform.localRotation.y);
            //print("6. lerp value: " + Quaternion.Lerp(currentPosition.localRotation, leftTileTarget.localRotation, step));
            steps++;
            if (transform.localRotation == leftTileTarget.localRotation)
            {
                print(steps);
                break;
            }
            yield return null;
        }
    }

I’ve got also similar function which lerp to target position also using 5% distance step:

    IEnumerator Test2()
    {
        int steps = 0;
        for (int i = 0; i < 20; i++)
        {
            float positionDistance = Mathf.Abs(currentPosition.localPosition.z - leftTileTarget.localPosition.z);
            float positionStepPercentageValue = positionDistance * .05f;  // move step float value necessary for calculating step percentage value
            float newPositionValue = Mathf.Abs(transform.localPosition.z) + positionStepPercentageValue;  //  new z value after incementation by moveValue
            float positionStep = newPositionValue / positionDistance;  // step calculated using new position and percentage value of step distance provided by CheckRectPosition()
            transform.localPosition = new Vector3(0, 0, Mathf.Lerp(currentPosition.localPosition.z, leftTileTarget.localPosition.z, positionStep));
            steps++;
            if (transform.localPosition == leftTileTarget.localPosition)
            {
                print(steps);
                break;
            }
            yield return null;
        }
        print(steps);
    }

My problem is rotation lerp - When I’m lerping to target rotation after first lerp I’m getting issue with decimal number:


Lerp step value is: 0,03043807 provided as a interpolation step.
But its lerping to 0,03074131 (minus is intended and it’s fine)
But the 0,0003 difference is generating huge miscalculation which results in finishing in 16 steps instead of 20…

And ideas what I’m doing wrong and how can I solve this?

This is a proper way to interpolate rotations:

interpolation

using UnityEngine;
public class InterpolateRotationInNSteps : MonoBehaviour
{
	[SerializeField] Transform _target;
	[SerializeField][Min(1)] int _numSteps = 20;
	#if UNITY_EDITOR
	void OnDrawGizmos ()
	{
		if( _target==null ) return;

		Vector3 pos = transform.position;
		Quaternion rot_initial = transform.rotation;
		Quaternion rot_target = _target.rotation;

		Gizmos.color = Color.black; Gizmos.DrawLine( pos , pos + rot_initial*Vector3.right );
		Gizmos.color = Color.white; Gizmos.DrawLine( pos , pos + rot_target*Vector3.right );

		for( int step=1 ; step<=_numSteps ; step++ )
		{
			float progress = (float)step / (float)_numSteps;
			Quaternion rot_now = Quaternion.Slerp( rot_initial , rot_target , progress );
			
			Gizmos.color = Color.Lerp( Color.blue , Color.green , progress );
			Gizmos.DrawLine( pos , pos + rot_now*Vector3.right );
		}
    }
	#endif
}

Your first line alone contains a math error that turns everything wrong:

float stepValue = currentPosition.localRotation.y - leftTileTarget.localRotation.y * .05f;

as 20-10*0.5 is 15 not 5.