Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Ego65 · Dec 01, 2015 at 02:35 PM · coroutinetimesmoothvaluefixedupdate

how to change a value over time in a coroutine ?

hey hey, first of all :i know that this kind of question has been asked many times before. i want to say that i was reading and then trying much to adapt it to my need but i didnt come to a solution.
i have a script in which the y component of transform.eulerangles is changed in an IEnumerator function using there a coroutine.

    IEnumerator y_rotation()
     {
         
         while (true) // run this forever and ever
         {
             if (is_attacked == true) // if in attack mode, do rotation logic
             {
                 //yRotation = Mathf.SmoothDamp(0,-90,ref Velocity,transTime);  
                 yRotation = -90.0f;
                 yield return StartCoroutine(Wait());
                 yRotation = 90.0f;
                 yield return StartCoroutine(Wait());
             }
             yield return null; // wait a single frame to let Unity breath
         }
     }

which is executed in FixedUpdate :

    void FixedUpdate()
     {
         transform.eulerAngles = new Vector3(0, yRotation, 0);
         rb.AddRelativeForce(Vector3.forward * thrust);
         rb.velocity = transform.forward * rb.velocity.magnitude;
     }

what i want to achiefe is that it takes about 1 second until yRotation = -90
i've tried it with mathf.lerp or mathf.smoothdamp nothing works, i even tried it with a for loop (....i++) but the value is in a while loop ! so my pc went on strike. I'm pretty confused now so i would be thankfully for any help.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ego65 · Dec 02, 2015 at 09:56 AM 0
Share

i've kept on trying. the only way i got the mathf.lerp to work was to set this in the update funct

 yRotation += $$anonymous$$athf.LerpAngle(0.0f, -90.0f, Time.deltaTime);  

this way its rotating permantly. so i thought i can fix that problem with declaring another coroutine = left(). but that doesnt really work just changing the value for 1 time. the problem is how to get the time thing like it does in update yRotation += Time.deltatime.
below is my complete script i have so far.

 using UnityEngine;
 using System.Collections;
 
 public class ExampleClass : $$anonymous$$onoBehaviour
 {
     public float thrust;
     public Rigidbody rb;
     public float yRotation = 0.0F;
     public bool is_attacked = false;
     public float turn_factor;
    
     public float y_left = 0.0f;
     public float mytime = 0.0f;
 
     void Start()
     {
         rb = GetComponent<Rigidbody>();
         StartCoroutine(y_rotation());
         StartCoroutine(left());
     }
 
     IEnumerator Wait()
     {
         yield return new WaitForSeconds(2);
         
     }
  
     void Update()
     {
         if (yRotation >= 360.0F)
         {
             yRotation = 0.0F;
         }
         if (yRotation <= -360.0F)
         {
             yRotation = 0.0F;
         }
         // yRotation += Input.GetAxis("Horizontal");      
     }
    
 
     void FixedUpdate()
     {
         
         transform.eulerAngles = new Vector3(0, yRotation, 0);
         rb.AddRelativeForce(Vector3.forward * thrust);
         rb.velocity = transform.forward * rb.velocity.magnitude;
     }
 
     IEnumerator left()
     {
         y_left += $$anonymous$$athf.LerpAngle(0.0f, -90.0f, Time.deltaTime);
         yield return new left();
     }
 
     IEnumerator y_rotation()
     {
         
         while (true) // run this forever and ever
         {
             if (is_attacked == true) // if in attack mode, do rotation logic
             {
                 //yRotation = -90.0f;
                
                 yield return StartCoroutine(left());
                 yield return StartCoroutine(Wait());
                 yRotation = 90.0f;
                 yield return StartCoroutine(Wait());
             }
             yield return null; // wait a single frame to let Unity breath
         }
     }
 }

  



 




2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Bunny83 · Dec 02, 2015 at 01:50 PM

If i understand you right you want, while "is_attacked" is true to smoothly pingpong rotate the object between -90 and 90 on the y axis? What's the initial rotation?

One approach would be:

 IEnumerator y_rotation()
 {
     while (true)
     {
         if (is_attacked) 
         {
             while (yRotation < 90f)
             {
                 yRotation += 90f * Time.deltaTime;
                 yield return null;
             }
             while (yRotation > -90f)
             {
                 yRotation -= 90f * Time.deltaTime;
                 yield return null;
             }
         }
         else
         yield return null; 
     }
 }

Note: It's fine when the angle becomes negative, so don't wrap it back to 360 outside of the coroutine or the coroutine can never reach -90. If you rotate the object somewhere else where you want to limit the rotation you might want to wrap it around at -180 and 180. Also you should rotate the object in Update, not in FixedUpdate. Otherwise you will see stuttering.

Another way would be to just use Mathf.PingPong in Update. You would need a second variable if you plan to allow other rotations outside the range of -90 to 90.

 float t = 0;
 float yRotation = 0;
 void Update()
 {
     if (is_attacked) 
     {
         t += 90f * Time.deltaTime;
         yRotation = Mathf.PingPong(t, 180f) - 90f;
     }
     transform.eulerAngles = new Vector3(0, yRotation, 0);
 }
Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ego65 · Dec 02, 2015 at 04:59 PM 0
Share

also thx for your reply ! what i want to achiefe is that this npc enemy flies wavy lines (snake like) when if(is_attacked). if not (until nothing else is declared) it should just fly straight forward
yRotation = 0. i guess thats what you mean : the initial rotation?
at the end it shall become part of an enemy AI. it will need a little bit to get through your suggestions, because i want to understand them and not only to copy and paste them.

cu soon :)

avatar image Ego65 · Dec 02, 2015 at 05:04 PM 0
Share

just an idea before : if it comes to a nice result being done with this coroutines, i think it would be interesting to set up a random value for waitinseconds() to make the behavior of the enemy not sooo easy to predict for the player!?

avatar image Ego65 · Dec 03, 2015 at 04:34 PM 0
Share

i've tried both of them and both are working. seems best for perfomance ( in my case ) is to calculate transformeulerangles still in the fixedupdate.
but i wonder why the turn is now so smooth? for sure i treid that also before : yRotation -= 90f * Time.deltaTime; but that was "stuttering"
is that avoid only by yield return null right after yRot.... ?

once more many thx for your help !
yours

avatar image Bunny83 Ego65 · Dec 03, 2015 at 05:31 PM 0
Share

yield return null; will make the coroutine wait one frame at this point. So it behaves just like Update. The loop does one iteration per frame. Time.deltaTime can only be used when you do something every frame since it contains the time between the last two frame. For example if your framerate is 60 frames per second, deltaTime will be 1/60 == 0.01666. If you accumulate the value of deltaTime every frame you will get a value of about 1.0 after 1 second. Since we multiply by 90 degrees we actually accumulate 1.5 degree each frame (==90 0.01666). If you add 1.5 to your value 60 times, you effectively have added 90 (1.5 60 == 90).

FixedUpdate is at no point something to gain performance. In your case it will just produce additional problems and make it less smooth. FixedUpdate should only be used when dealing with continuous forces, physics or accelerated movement. It's actually called from the internal physics loop. It doesn't run at a constant rate. It is just "fixed" to ensure a constant callrate over one second. FixedUpdate runs at the same time Update runs, but sometimes it might simply skip a call or even call it twice in a row to "fix" the time error. $$anonymous$$ovement in FixedUpdate is naturally more jerky than movement done in Update.

avatar image Ego65 Bunny83 · Dec 04, 2015 at 01:01 PM 0
Share

that's what i call a real in depth going explanation :) i think i did understand it basically. but the thing with the performance " in my case" was: the movement of this enemy works well in both cases but that the position of a cube which is attached to this enemyship as a child to to be used in my 3d radar wasn't fast enough updated
( stuttering movement ). i had this prob before(but that is another topic):
http://answers.unity3d.com/questions/1101263/line-renderer-jumps-when-start-end-positons-belong.html

i was playing around in the time manager again set the max. allowed time to 1 and it seems this way a can reduce that prob to a $$anonymous$$imum but only when yRot.... is calculated in Fixedupdate. a real mysterious secret of progging in unity for a beginner :)

avatar image
0

Answer by Cherno · Dec 02, 2015 at 11:21 AM

Try this, and get rid of those left and wait CoRoutines.

    float turnSpeed = 3.33f;
 
  public IEnumerator Turn()
    {
                while (true) // run this forever and ever  
                {
                        if (is_attacked == true) // if in attack mode, do rotation logic
                        {
                       yRotation  += turnSpeed;
                        }
                  yield return null;
               }
 }
 

However, it would be far easier to just use Transform.Roate in Update of FixedUpdate to rotate directly.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Ego65 · Dec 02, 2015 at 04:36 PM 0
Share

thx ! i already thought the same . seems it was a basic misunderstanding of $$anonymous$$e that it would be necessary to do this in coroutines. as well as it was hard enough for me to get it. i'm still learning.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Time Manager Class Implementation Like Coroutine in Unity 1 Answer

RPG Action Progress Bar always same speed 1 Answer

FixedUpdate has stopped working 0 Answers

trying to regulate character speed. 1 Answer

Slow update best practice 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges