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 Aedous · Oct 26, 2015 at 12:02 PM · c#coroutineframeratecoroutinestime.deltatime

Using Time efficiently regardless of current frame rate.

Hello!

I hope this is a simple fix for someone out there, I've looked around for a fix and tried a few things, but nothing seems to give me the correct result.

The main issue is using a coroutine like this:

 float elapsedTime = 0f;
 float timeToComplete = 2f;
 while(elapsedTime < timeToComplete)
 {
         elapsedTime += Time.deltaTime;
         yield return 0;
 }
 //Do stuff


I use this function to run all my timer countdown code, but what I've noticed is if I get a drop in frame rate the time for it to complete is slightly longer than it should be. In my head this makes sense simply because Time.deltaTime will return a number from how long it took for it to complete this frame. So if the game is running slower than it should take longer. So I tried replacing Time.deltaTime and using Time.time to get this instead:

 float elapsedTime = 0f;
 float timeToComplete = Time.time + 2f;
 while(elapsedTime < timeToComplete)
 {
         elapsedTime = Time.time;
         yield return 0;
 }
 //Do stuff

This however gives me the same behaviour as using Time.deltaTime.. Isn't there a time function that will give me the same result each time regardless of the frame rate? I just want to count to 'X' seconds and have something happen at the end, regardless of how much frame rate I have.

Any help would be greatly appreciated!!

Comment
Add comment · Show 7
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 Bonfire-Boy · Oct 26, 2015 at 12:26 PM 0
Share

The problem is that the interval between frames (Time.deltaTime) is a) finite and b) not fixed. So it's extremely unlikely that at the end of the final frame in this process (the one that where elapsed is no longer less than timeToComplete), elapsed will end up being exactly equal to timeToComplete. You'll always overshoot.

Chances are you'll be best off just refactoring things in such a way that it's no longer a problem that the process takes a fraction of a second more than timeToComplete, to complete. By the way, are you sure it is a problem? How much of an overshoot are you actually getting?

But an alternative you could try is using fixedUpdate ins$$anonymous$$d of a coroutine, that way the interval becomes predictable.

avatar image Aedous Bonfire-Boy · Oct 26, 2015 at 03:53 PM 0
Share

I'm not really concerned with the ti$$anonymous$$g to always hit the 'timeToComplete' mark, because it will always over shoot, the main problem is the noticeable difference of how far it goes when the game slows down, for example I'm using it to slow my character down after "Dashing". At a normal frame rate you slow down very quickly, but at a slow frame rate you slow down very slowly which in turn makes it look like your dashing much further than it should be. I've even tried messing around with 'Time.time' using 'return new WaitForFixedUpdate' but to no luck, I always get a different result when the frame rate is low.

I even tried just recording the differences in time just to see if they were close enough:

  float elapsedtime = Time.time;
             float endTime = Time.time + delay;
             Debug.Log("Start Time : " + elapsedtime + " > " + endTime);
             while (Time.time < endTime)
             {
                 yield return null;
             }
             Debug.Log("End Time : " + (Time.time - elapsedtime) + " > " + endTime );

   

The difference in time is about 2 times larger when your frame rate is low. Which is very odd. The only thing I'm thinking now is Coroutines are just bad to use when you have a low frame rate.

avatar image Bonfire-Boy Aedous · Oct 26, 2015 at 04:09 PM 0
Share

Are you saying the overshoot is doubled when the frame rate is slow? On the face of it, that doesn't seem particularly surprising or excessive. What's the size of the difference?

It sounds to me that the countdown might be a red herring and the issue might be to do with what you're doing during/after this countdown (for example how you're slowing the character down) rather than with the countdown itself. For example if one were to reduce something's speed by a fixed amount in every frame, rather than by an amount that depends on deltaTime, then one would expect the deceleration to correlate with the frame rate.

To eli$$anonymous$$ate frame rate differences, you may just need to make sure that (the extent of) whatever you're doing in "DoStuff" is dependent on how long it is since you last "did stuff".

Generally speaking, if ti$$anonymous$$g is that critical, I'd have thought that using FixedUpdate is probably the way to go.

Show more comments
Show more comments
avatar image Aedous Bonfire-Boy · Oct 26, 2015 at 04:39 PM 0
Share

@Statement I simply just call the coroutine to start the slowing down the character.

@BonfireBoy I'm going to try what you said, and try and work out how long it has been since the timer and apply that to how long it should take to slow down, that sounds like a reasonable way to go about it to accommodate the frame rate issue.

0 Replies

· Add your reply
  • Sort: 

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

Need opinions, or facts, about how to best go about programming this behavior. Basically Redstone. 0 Answers

Toggling bools automatically using coroutines 1 Answer

Trouble Resuming after Yielding while Inside Coroutine 1 Answer

How would I make a timer frame independent? 1 Answer

Multiple Cars not working 1 Answer


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