Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

355
Views
Unity 2D. How to rotate an object smoothly inside a Coroutine?

I'm newbie here, but will try to describe as clear as I can. (it's not that important, just to clarify) So I want to rotate an object for 405deg in 1 second only once, when space is pressed. I've thought it should be done using coroutines, so I've wrote something like this:

private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StopAllCoroutines(); //to prevent overlapping
            StartCoroutine(Rotate());
        }
    }

    IEnumerator Rotate()
    {
        //where final finalRotation is a rotation i want to get in a result
        Quaternion finalRotation = Quaternion.Euler(0, 0, 405) * transform.rotation;
/*
using do..while to make sure that object will rotate even in case it's in same rotation as finalRotation
*/
        do
        {
            //should smoothly rotate an object for 405deg in 1 sec but it doesnt
            transform.Rotate(Vector3.forward, 405f * Time.deltaTime / 1f);
        } while (transform.rotation != finalRotation);
        yield return 1;
    }

The code above works fine and everything is ok except one, it rotates an object instantly and not smoothly. I mean, if I use that line of code in Update, everything go smoothly

transform.Rotate(Vector3.forward, 405f * Time.deltaTime / 1f);

So my questions:

  1. Why does it rotate smoothly in Update, but instantly in the coroutine;

  2. and how can that be fixed?

Thanks in advance, once again, sorry if I made some mistakes when making a topic.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

It updates instantly in the coroutine because you only yield when the rotation is complete. The frame wont be rendered until every pending/running coroutine yields or completes, so here your rotation completes and then finally the frame is rendered, making it an instant rotation.

Instead, you should yield in the loop.

You should also be aware that Quaternion finalRotation = Quaternion.Euler(0, 0, 405) * transform.rotation; and transform.Rotate(Vector3.forward, 405f); can have different results depending on parent object rotations, because they rotate in different spaces, the first rotating in global and the second rotating in local. This may result in the loop as written actually never ending.

Another problem is that there is no guarantee that summing up Time.deltaTime values will ever add up to 1f. Suppose on the very first frame, lag occurs, causing Time.deltaTime to be huge, 2f. You can see how it might never end as a result. As an alternative, you should remember the start rotation, then on each frame calcuate the rotation from that frame, then apply it that frame.

Altogether:

IEnumerator Rotate()
{
    Quaternion startRotation = transform.rotation;
    float endZRot = 405f;
    float duration = 1f;
    float t = 0;

    while (t < 1f)
    {
        time = Mathf.Min(1f, t + Time.deltaTime/duration);
        Vector3 newEulerOffset = Vector3.forward * (endZRot * t);      
        // global z rotation
        transform.rotation = Quaternion.Euler(newEulerOffset) * startRotation;
        // local z rotation
        // transform.rotation = startRotation * Quaternion.Euler(newEulerOffset);
        yield return null;
    } 
}
over 4 years ago · Santiago Trujillo Report

0

yield return null will wait one frame inside a coroutine. Right now you have placed the yield return 1; outside the while loop, so it wont do anything. In this situation I whould lerp between the two rotations in a while loop that goes from 0->1

or (if you dont want to do any of this stuff and dont care for a bit of bloat) use leantween, https://assetstore.unity.com/packages/tools/animation/leantween-3595

over 4 years ago · Santiago Trujillo Report

0

In the place where you rotate it one increment you have to wait for some time. Try

yield return new WaitForSeconds(0.1);

Also while I was typing this someone else answered.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!