Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
2
Question by Strip · May 16, 2013 at 02:54 PM · timerfixedupdatetiming

Is it possible to create a second FixedUpdate function running at different rate?

Is it possible to create a second FixedUpdate function running at different step rate?

I have the need to run a block of code at a much faster rate than the physics require. Given that the code is used in a timing system I need very repeatable results from the time functions. Although I can run the fixed step at 0.001 and run the bulk of the code only on selected cycles the Unity physics is still being run at 1000 Hz.

I have considered using an Invoke style function but it does not have the accuracy required. Is there a way to run the fixed update rate at 500 Hz and use a delay function to call a block of code twice in one FixedUpdate call?

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

2 Replies

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

Answer by Bunny83 · May 16, 2013 at 05:36 PM

Yes, it's possible to implement an independent FixedUpdate function. Keep in mind that "Fixed" doesn't mean "fix-rate" or "constant-rate". It means that it is "fixed" each Update. Here's a sample class that implements a custom FixedUpdate (Updated version on the wiki):

 // C#
 public class CustomFixedUpdate
 {
     private float m_FixedDeltaTime;
     private float m_ReferenceTime = 0;
     private float m_FixedTime = 0;
     private float m_MaxAllowedTimestep = 0.3f;
     private System.Action m_FixedUpdate; 
     private System.Diagnostics.Stopwatch m_Timeout = new System.Diagnostics.Stopwatch();
 
     public CustomFixedUpdate(float aFixedDeltaTime, System.Action aFixecUpdateCallback)
     {
         m_FixedDeltaTime = aFixedDeltaTime;
         m_FixedUpdate = aFixecUpdateCallback;
     }
 
     public bool Update(float aDeltaTime)
     {
         m_Timeout.Reset();
         m_Timeout.Start();
 
         m_ReferenceTime += aDeltaTime;
         while (m_FixedTime < m_ReferenceTime)
         {
             m_FixedTime += m_FixedDeltaTime;
             if (m_FixedUpdate != null)
                 m_FixedUpdate();
             if ((m_Timeout.ElapsedMilliseconds / 1000.0f) > m_MaxAllowedTimestep)
                 return false;
         }
         return true;
     }
 
     public float FixedDeltaTime
     {
         get { return m_FixedDeltaTime; }
         set { m_FixedDeltaTime = value; }
     }
     public float MaxAllowedTimestep
     {
         get { return m_MaxAllowedTimestep; }
         set { m_MaxAllowedTimestep = value; }
     }
     public float ReferenceTime
     {
         get { return m_ReferenceTime; }
     }
     public float FixedTime
     {
         get { return m_FixedTime; }
     }
 }

Instead of feeding deltatime you could also take out the internal reference time and feed in Time.time. However i think that way it's more flexible ;)

You can pass your desired timestep as well as a a delegate which will be called with the choosen rate.

Note: the MaxAllowedTimestep is very important. Without this check a heavy calculation inside your custom FixedUpdate function can almost freeze your game. That's because when the claculation takes longer than the current deltaTime it will increase the next deltaTime which will result in even more calls of your CustomFixedUpdate function which results in a endless growing deltaTime and you get quickly tomillions of calls per Update. The MaxAllowedTimestep limits the execution of your delegate if it takes longer than this timespan.

Note: I've not tested the class ( i've just written it ;) ), but it should work.

Use it like this:

 // C#
 public class SomeMonoBehaviour : MonoBehaviour
 {
     private CustomFixedUpdate m_FixedUpdate;
     void Start()
     {
         m_FixedUpdate = new CustomFixedUpdate(0.001f, MyFixedUpdate);
     }
     void Update()
     {
         m_FixedUpdate.Update(Time.deltaTime);
     }
     void MyFixedUpdate()
     {
         // Do some fancy stuff every 0.001 seconds.
     }
 }

This is exactly how Unity's FixedUpdate function works. Inside MyFixedUpdate you might want to use:

  • m_FixedUpdate.FixedDeltaTime instead of Time.fixedDeltaTime (or Time.deltaTime)

  • m_FixedUpdate.FixedTime instead of Time.fixedTime

Just because it fits the topic: How FixedUpdate works ;)

Comment
Add comment · Show 2 · 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 Strip · May 16, 2013 at 07:27 PM 0
Share

Thank you Bunny83, I was not optimistic that I was going to hear of a solution and yet here you provide it turn key. With a little bit of find/replace and moving my code over to your function I was up in running in no time.

avatar image DrKucho · May 28, 2014 at 12:14 AM 0
Share

Hello , and thanks for that piece of code Bunny 83 , but i have tried it and i get all the executions of myFixedUpdate() imediately one after the other, i printed Time.time to the log screen inside myFixedUpdate and i get about 50 or 60 prints with the exact time , followed by another 50 or 60 prints with a increased time value but all of them the same

is this how it is supposed to work? cause i don't think this is very usable

avatar image
1

Answer by Kristian · May 16, 2013 at 03:26 PM

I'm not sure of the accuracy of this approach in small scale intervals, but try something along these lines:

     void Start()
     {
         StartCoroutine(MyUpdate());
     }
 
     IEnumerator MyUpdate()
     {
         while (true)
         {
             yield return new WaitForSeconds(1f / 1000f);
 
             // Do Stuff
         }
     }
Comment
Add comment · Show 2 · 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 Owen-Reynolds · May 16, 2013 at 03:51 PM 1
Share

Small yields don't work. Yield looks like a traditional "sleep" command, but it really waits an integer number of frames until the time has passed.

avatar image Bunny83 · May 16, 2013 at 04:51 PM 1
Share

Exactly, coroutines which are waiting for a "WaitForSeconds" are processed once per frame (AFAI$$anonymous$$ right after Update is processed). So you can't get a higher rate as the current fps count.

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

17 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

Related Questions

Is FixedUpdate() not called at the same time for all object? 1 Answer

Update() calls start several seconds after launch 0 Answers

Timing pulses from microphone 0 Answers

Project Hyerarchy problem? 0 Answers

my timer isnt working for my firerate! it instantiates too many objects at a time,HOw can i get my shot timer working properly? it instantiates too many objects at a time 2 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