The way you are using it currently is like this:
Each frame you are looking at your current rotation and your target rotation. Then you are moving your rotation to some percentage of the remaining rotation. The percentage is Time.deltaTime * whatever your rotation speed is. So your rotation will go something like this (I made up some numbers for an easy example):
Let’s say you have your rotation set to 50.
Let’s say your frame rate is a constant FPS and each frame takes .016 seconds.
Therefore each frame your “t” parameter will be (50 * .016) = 0.8, which means you will move 80% of the remaining way towards your target rotation.
Frame 1: current rotation: 0°, target rotation = 100°. 80% of 100 is 80. Result = 80°
Frame 2: current rotation: 80°, target rotation = 100°. 80% of 20 is 16. Result = 96°
Frame 3: current rotation: 96°, target rotation = 100°. 80% of 4 is 3.2. Result = 99.2°
Frame 4. current rotation: 99.2°, target rotation = 100°. 80% of .8 is .64. Result = 99.84°
And so on forever. You will never actually reach 100° of rotation because you are only moving 80% of the way there each frame.
The way to use Lerp properly is the following:
As soon as you know what your target rotation is, save it in a variable. Also save your current rotation in a variable. In your case your target direction is what we calculated as “rotation” in your example code. So as soon as you set WaypointPosition do the following calculation:
Quaternion startRotation;
Quaternion targetRotation;
float startedRotatingAt;
float willEndRotatingAt;
bool isRotating = false;
void SetupForLerp() {
var rotationDirection = WaypointPosition - movingObject.transform.position;
if (rotationDirection == Vector3.zero) return;
var currentRotation = movingObject.transform.rotation.eulerAngles;
if (ignoreXRotation) rotationDirection.x = currentRotation.x;
if (ignoreYRotation) rotationDirection.y = currentRotation.y;
if (ignoreZRotation) rotationDirection.z = currentRotation.z;
var rotation = Quaternion.LookRotation(rotationDirection);
startedRotatingAt = Time.time;
// Our starting rotation is the current rotation
startRotation = movingObject.transform.rotation;
// Our ending rotation is what we calculated above...
targetRotation = rotation;
float degreesToRotate = Quaternion.Angle(startRotation, targetRotation);
float timeItWillTake = degreesToRotate / rotationSpeed;
willEndRotatingAt = Time.time + startedRotatingAt;
isRotating = true;
}
Then, in TransformRotationHandler() do this:
private void TransformRotationHandler() {
if (!isRotating) {
// No need to do anything if we're not currently doing a rotation
return;
}
// How far between startedRotatingAt and willEndRotatingAt are we? This function will return 0 if we just started, .5 if we're halfway between them, .9 if we're 90% of the way there, 1 if we're at the end time, etc.
float t = Mathf.InverseLerp(startedRotatingAt, willEndRotatingAt, Time.time);
movingObject.transform.rotation = Quaternion.Lerp(startRotation, targetRotation, t);
if (t >= 1) {
// We're done rotating for now.
isRotating = false;
}
}
Note that “rotationSpeed” is expressed in degrees per second. So you might have to change the value to get the speed you want. But the speed will now be constant across the whole rotation.