I am rotating my camera to lookat a target object using Quaternion. I am using Quaternion.LookRotation and Quaternion.Slerp to make the camera rotate smoothly inside coroutine. Unfortunately the camera jitters a lot when rotating. How do I make the rotation smooth with my current code?
Quaternion targetRotation;
public Transform lookAtObject;
IEnumerator RotateTowardsTarget () {
var duration = 2.0f;
for (float t = 0.0f; t < duration; t = Time.deltaTime) {
targetRotation = Quaternion.LookRotation (lookAtObject.position - transform.position);
transform.rotation = Quaternion.Slerp (transform.rotation, targetRotation, t / duration);
yield return null;
}
}
CodePudding user response:
You currently always start the lerp at the current rotation towards the target.
In your usecase what you rather want to do is store the initial rotation and rather interpolate between the initial and target rotation like
IEnumerator RotateTowardsTarget ()
{
var duration = 2.0;
// store the initial and target rotation once
var startRotation = transform.rotation;
var targetRotation = Quaternion.LookRotation (lookAtObject.position - transform.position);
for (var timePassed = 0.0f; timePassed < duration; timePassed = Time.deltaTime)
{
var factor = timePassed / duration;
// optionally add ease-in and -out
//factor = Mathf.SmoothStep(0, 1, factor);
transform.rotation = Quaternion.Slerp (startRotation, targetRotation, factor);
yield return null;
}
// just to be sure to end up with clean values
transform.rotation = targetRotation;
}
This will make the camera go from the current to the new rotation linear within 2 seconds
CodePudding user response:
Slerp takes third parameter as progress not as actual time you can do this
void Update () {
StartCoroutine(RotateOverTime(transform.rotation,
lookAtObject.rotation, 1f / speed));
}
IEnumerator RotateOverTime (Quaternion originalRotation, Quaternion
finalRotation, float duration) {
if (duration > 0f) {
float startTime = Time.time;
float endTime = startTime duration;
transform.rotation = originalRotation;
yield return null;
while (Time.time < endTime) {
float progress = (Time.time - startTime) / duration;
// progress will equal 0 at startTime, 1 at endTime.
transform.rotation = Quaternion.Slerp (originalRotation,
finalRotation, progress);
yield return null;
}
}
transform.rotation = finalRotation;
}
You can now send in duration as seconds