1
\$\begingroup\$

I would like to change a camera's rotation and position from its current position and rotation to a destination position and rotation.

This should happen within a specific time (seconds).

I call this void "pRotateAndPosition" in each Public void Update().

However, I'm having trouble getting the 3rd argument for Lerp (time) correct.

Could anybody tell me where my mistake(s) are?

Thank you.

private void pRotateAndPosition()
{
    _TimeElapsed += (Time.deltaTime / TimeInSecondsInWhichWeWantToGetToFinalRotationAndPosition);

    if (_TimeElapsed >= TimeInSecondsInWhichWeWantToGetToFinalRotationAndPosition)
    {
        _StopCallingThisVoid = true;//don't call this anymore

        //set the final position and rotation in case we're not completely there yet
        _camera.transform.localRotation = Quaternion.Euler(goalRotation);
        _camera.transform.localPosition = goalPosition;
        return;
    }

    float fTime = _TimeElapsed;//absolutely not sure about this one

    _camera.transform.localRotation = Quaternion.Lerp(_camera.transform.localRotation, Quaternion.Euler(goalRotation), fTime);
    _camera.transform.localPosition = Vector3.Lerp(_camera.transform.localPosition, goalPosition, fTime);
}
\$\endgroup\$
1
\$\begingroup\$

In addition to 'Alex F's answer:

You were handling the elapsed time badly. The stop condition was wrong in combination with how you were counting time.

Edit: You also need to save the position/rotation your camera has at the beginning of the Lerp action, otherwise you will not interpolate correctly! You can't just plug in the current position into the Lerp function again.

private void pRotateAndPosition()
{
    // Count the real elapsed time, not some scaled pseudo-time
    _TimeElapsed += Time.deltaTime;

    if (_TimeElapsed >= TimeInSecondsInWhichWeWantToGetToFinalRotationAndPosition)
    {
        _StopCallingThisVoid = true;//don't call this anymore

        //set the final position and rotation in case we're not completely there yet
        _camera.transform.localRotation = Quaternion.Euler(goalRotation);
        _camera.transform.localPosition = goalPosition;

        return;
    }

    // This will be (almost) zero at the beginning and ~1 when finished
    float fTime = _TimeElapsed / TimeInSecondsInWhichWeWantToGetToFinalRotationAndPosition;

    // The Lerp time should always be between 0 and 1. Time 0 gives you the start value, 1 the goal value, 0.5 is half-way between them.
    // Maybe the Slerp function looks smoother: https://en.wikipedia.org/wiki/Slerp Unity has this too
    _camera.transform.localRotation = Quaternion.Slerp(initialCameraRotation, Quaternion.Euler(goalRotation), fTime);
    _camera.transform.localPosition = Vector3.Lerp(initialCameraPosition, goalPosition, fTime);
}

You might want to try S(pherical)lerp with quaternions, just try out which one looks better to you.

For positions Lerp is the right choice, you want to move in a linear fashion most of the time.

\$\endgroup\$
2
\$\begingroup\$

I think you are slightly confused about what Lerp does (although it's very possible that I just don't understand your code and what's calling it). It takes a starting configuration, an ending configuration, and another value. The other value simply tells you how far to go between the two configurations. Since that explanation is kind of confusing, here's an example. Let's say you're Lerping between 1 and 5 (using Mathf.Lerp). If the third argument is 0, you'll get 1, and if it's 1, you'll get 5. If it's 0.5, you'll get 3.

With that out of the way, here are some possible solutions to your problem.

  1. Coroutines: coroutines let you run a function alongside your main function. See the link for more information; looking at the first example, using f as the third argument to Lerp should achieve the effect you want (I'm assuming that you can modify the for loop).

  2. The other option that springs to mind is to emulate a coroutine inside your Update function, by using a private variable to store how far along you are in the Lerp.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.