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 TharosTheDragon · Nov 26, 2017 at 12:20 AM · c#timeframeratetime.deltatime

Is there any way to determine Unity's actual target frame rate?

My code allows the user to choose how many calculations are performed per second. I have a coroutine that can yield return many times in a row if the number selected is low, or it can perform the calculation many times in a row without yielding if the number selected is high. In order to do that, my code needs to know the time between yields. So I do something like this:

 timeWaited += Time.deltaTime;

However, if the number of calculations is very high, Time.deltaTime could grow larger, and the larger Time.deltaTime is the more calculations would be performed. It's a vicious cycle that could easily crash my program. So instead of using Time.deltaTime I want to use the frame rate that Unity is trying to achieve rather than the one it happened to have on that frame.

 timeWaited += targetDeltaTime;

I can do better than that, though. With that code I can avoid a vicious cycle, but it still has no way to recover if the calculations on each frame are too long every frame. So I can help by making it perform fewer calculations when Time.deltaTime is high.

 timeWaited += targetDeltaTime * targetDeltaTime  / Time.deltaTime;

But how do I get targetDeltaTime? According to the Application.targetFrameRate documentation, Unity's target frame rate varies by platform. Does Unity have a way to return that platform-specific target frame rate? Ideally there would be some function that would return Application.targetFrameRate if it's in effect (is not set to -1 and QualitySettings.vSyncCount is set to 0), or the platform's default frame rate if Application.targetFrameRate is being ignored.

EDIT: As requested, here is more of my code.

         public IEnumerator SearchDepthFirst ()
         {
             // ...
             while ( nodesRemain )
             {
                 // ...
                 while ( ShouldYield() )
                 {
                     yield return null ;
                 }
                 // ...
             }
             // ...
         }
 
         private bool ShouldYield ()
         {
             // ...
             if (SecondsWaited < SecondsPerNode)
             {
                 SecondsWaited += SecondsPerFrameSquared / Time.deltaTime ;
                 return true ;
             }
             else
             {
                 SecondsWaited -= SecondsPerNode ;
                 return false ;
             }
         }

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Nov 26, 2017 at 12:43 AM

First of all it can't crash your game since Time,deltaTime has a max value of 0.3333 (or 0.3 can't remember). So even when a frame takes longer than that value, deltaTime will not grow above this value.


You may want to have a look at my CustomFixedUpdate helper class which does pretty much the same thing as Unity does for it's own FixedUpdate, but can run at any framerate you like. It also has a safety check (which is disabled by default since Time.deltaTime is already limited).


If you actually don't require / want a certain number of iterations per second but just a "load limiter" you may just want to check Time.realTimeSinceStartup each iteration.


To me this line make no sense:

 timeWaited += targetDeltaTime * targetDeltaTime  / Time.deltaTime;

This will make the time step even smaller when the framerate goes down. So if you yield based on the passed "timeWaited" you will actually do more calculations when the framerate goes down. I think you should post more code about your actual logic in your coroutine.

Comment
Add comment · Show 6 · 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 unityBerserker · Nov 26, 2017 at 12:31 PM 1
Share

Visualization of $$anonymous$$aximum Allowed Timestep. alt text

time-fps-2-lo-fps.png (22.9 kB)
avatar image TharosTheDragon unityBerserker · Nov 26, 2017 at 05:54 PM 0
Share

This makes it look like $$anonymous$$aximum Allowed Timestep only affects FixedUpdate.

avatar image unityBerserker TharosTheDragon · Nov 26, 2017 at 11:38 PM 0
Share

Picture is part of my explanaion of Time class. F - Physic loop, U- main loop.

$$anonymous$$aximum Allowed Timestep affects physics loop. Physics loop must be always be invoked in fixed timesteps measured in game time (Time.time). If main loop (in which is Update) is invoked rarery we will see jittering movements of objects because physic loop will be updated few times. To prevent that we must stop invoking physic loop. But physic loop must be invoked in fixed timesteps. So we for a moments stop measuring time. $$anonymous$$aximum Allowed Timestep deter$$anonymous$$e when to stop time for moment. If time between Updates is greater then $$anonymous$$aximum Allowed Timestep then we stop time for moment.

avatar image TharosTheDragon · Nov 26, 2017 at 06:39 PM 0
Share

This will make the time step even smaller when the framerate goes down.

Did you mean "when the framerate goes up"? Remember that frame rate and deltaTime are inverses. If I divide by deltaTime, that means the bigger deltaTime is the fewer calculations I'll perform and vice versa.

avatar image Bunny83 TharosTheDragon · Nov 26, 2017 at 07:15 PM 0
Share

No i did mean it the way i said. However now that you have posted your ShouldYield method i can only say, it makes no sense. You have your return values reversed. As long as "SecondsWaited" is smaller than "SecondsPerNode" you currently yield. So you yield every iteration until SecondsWaited is equal or greater. In this case you do not yield one time. This makes not much sense. This will execute one iteration once every frame and from time to time you do two iterations in one frame. The other way round would make more sense.


However as i said the lower the frame rate gets (that means deltaTime gets larger), the slower you reach your timeout value. $$anonymous$$eep in $$anonymous$$d that you divide the value you're going to add to your wait time by deltaTime. So the bigger deltaTime is, the smaller the change of your SecondsWaited variable gets each iteration. So it requires more iterations to actually hit your limit.

avatar image TharosTheDragon Bunny83 · Nov 26, 2017 at 09:07 PM 0
Share

Well getting into the $$anonymous$$utia of my implementation is a bit of a tangent here and doesn't have much to do with my question, but I'll try to explain. $$anonymous$$y code may be hard to understand because it's been complicated by my slowdown-correction code. So to explain it more easily, imagine that the line in question reads:

 SecondsWaited += Time.deltaTime ;

You are correct that I yield every time SecondsWaited is smaller than SecondsPerNode. SecondsPerNode is something the user is able to influence directly to slow down or speed up the process. Remember that the point of this admittedly strange-looking algorithm is to allow either one calculation in many frames or many calculations in one frame or anything in between depending on the value of SecondsPerNode.

So let's say the user wants is really slow to see what's going on. SecondsPerNode will be really high, so it will take a long time for SecondsWaited to get bigger than SecondsPerNode. Once it does, SecondsWaited will go down to something close to zero and ShouldYield will return false meaning the inner while loop will end and one calculation can occur. In the mean time, SecondsWaited grows by a little bit each frame until it's big enough to trigger a calculation.

Now let's say the user doesn't want to wait and so SecondsPerNode is really low. After the first yield, SecondsWaited will be much larger than SecondsPerNode and so ShouldYield() will return false many times in a row, allowing many calculations in one frame. After each calculation ShouldYield() is called and SecondsWaited shrinks a little smaller until finally it's smaller than SecondsPerNode and the coroutine can yield until the next frame.

Let me know if that explanation makes sufficient sense before I explain why I'm now dividing by Time.deltaTime.

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

74 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Using Time efficiently regardless of current frame rate. 0 Answers

How does Time.deltaTime provide smoother physics functions? (Frame rate question) 2 Answers

Having trouble increasing the spawning speed of explosions 0 Answers

Do i need to use Time.Deltatime while using mouse axes for rotation? 1 Answer

Time.DeltaTime doesn't seem to be correctly 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