0
\$\begingroup\$

Note, this happens on click and not in the update cycle

I have a game object that i rotate at a given angle, around a point without a time component like this(works as intended):

void Rotate(a)
{
    var parent = transform.parent;
    Vector3 point = new Vector3(0, 0, 0);
    Vector3 axis = new Vector3(0, 0, 1);

    parent.transform.RotateAround(Pivot.bounds.center, axis, a);
}

note that the parent is an empty to manipulate the anchor point

I wish to animate the rotation over time, however each method produces an inaccurate result. The two functions I have tried:

IEnumerator RotateOverTime(float byAngles, float inTime)
{
    var parent = transform.parent;
    Vector3 axis = new Vector3(0, 0, 1);

    var stepAngle = byAngles/ (inTime/ 1000f);

    float timer = 0;
    while (timer <= (inTime/ 1000f))
    {
        parent.transform.RotateAround(Pivot.bounds.center, axis, stepAngle * Time.deltaTime);
        timer += Time.deltaTime;
        yield return null;
    }
    yield return null;
}

IEnumerator RotateMe(Vector3 byAngles, float inTime)
{
    var parent = transform.parent;
    var fromAngle = parent.transform.rotation;
    var toAngle = Quaternion.Euler(parent.transform.eulerAngles + byAngles);
    for (var t = 0f; t < 1; t += Time.deltaTime / inTime)
    {
        parent.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t);
        yield return null;
    }
}

The Problem:

The above two methods doesn't rotate the object by the exact amount of degrees, see image below where the angle in question is 90deg. You can clearly see by the grid what the issue is

Starting Position

End Position

\$\endgroup\$
1
  • \$\begingroup\$ Have you considered using a while loop rather than a for loop in your coroutine that clears once the rotation is actually the desired value? \$\endgroup\$
    – Weckar E.
    Aug 7 '20 at 19:29
2
\$\begingroup\$

The problem with the second routine is this:

for (var t = 0f; t < 1; t += Time.deltaTime / inTime)

That continues the loop while t < 1. The loop will stop when t >= 1, which means the Lerp will never execute while t = 1.

You could change it to t <= 1, but it's extremely unlikely that t will ever exactly equal 1, so that may not help anyway.

The solution for either function is dead simple: add this line to the end of your coroutine:

parent.transform.rotation = toAngle;
\$\endgroup\$
1
  • \$\begingroup\$ Such a simple solution, dont know how i missed it thanks. \$\endgroup\$
    – Vince
    Aug 7 '20 at 20:54

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.