Precise frame timings in Unity

So I would like to have a way to have unity run update() at a precisely fixed interval. As I understand it, the best way to do this would be to force frame updates to occur at a given frequency.

So far, I have been using this article.) as a reference, as well as a few somewhat-related posts I found on the forum.

My problem is that I am trying to align events that occur in unity with events from an external device. The external device’s polling rate is very precise so I don’t have a problem on that end, however I will need to be running both for ~1 hour, and ideally I would like to be able to use the frame rate, and correspondingly any information I pull from Unity during Update() as a measure of time over the hour.

My understanding is that Unity doesn’t exactly like being made to run at a precise frame rate, but this is more an issue of when Unity is unable to run at the desired frame rate due to processing demands, rather than needing to throttle the frame rate down from max. Fortunately my game is not computationally intensive (as in it runs on my machine at 10-20x the desired fps) so this shouldn’t be an issue for me.

I’m planning to test the methods mentioned in the article myself using a photoresistor attached to an arduino, but I am a complete novice when it comes to this and obviously having any test take an hour is not ideal when you’re not sure what is likely to work and what won’t, so I was hoping someone on this forum with more experience than me might be able to weigh in and give some recommendations as to how I could achieve what I am trying to do.

I know it might not be realistic to expect exactly 60 frames per second, every second for an hour even with a game that doesn’t need a lot of computational power on a high end machine, but this is the ideal, and my margin for error is extremely low so at worst I would need any drift in average FPS/minute to be as small as possible, and I could do post alignment by regularly getting time stamps over the hour.

edit: I should mention from the testing I have already done with the Coroutine method mentioned in the article, while it does throttle the frame rate down to 60fps, I notice using a basic FPS display that it seems to drop 1 frame every 3-5 seconds. Obviously for regular use this wouldn’t be a problem, but for me that single frame will compound over an hour and doesn’t occur at a regular interval so I’m anticipating that when I test this properly for an hour it might not suit my needs.

Update() is not designed for the level of precision it sounds like you need. Unity is a video game engine, it doesn’t really matter in a video game whether actual in-game timings are off by 1% or so.

Coroutines effectively run in sync with all the other Unity update functions, so they will generally have the same problems that using the Update() function would.

Your best bet would be to look at spinning up a separate thread for this purpose. This way, it won’t matter what is going on with Unity’s main thread, and you can implement your own timing system. If you need Unity to do anything in the main thread (e.g. updating some view), you can push all the data from that thread into a queue and read it from Update.

1 Like

Ok thanks for the reply.

I think the most important thing I need to be able to do is have a precise timing for the position of the player at any given time, as well as when the player enters triggers. Using the player position as an example, at the moment I am just saving the coordinates to a .csv per frame, but if I wanted to use a separate thread, in my example would I be using the separate thread to tell Unity when to run update, or would I be using it to pull the player coordinates from Unity at specific times to write to my .csv? Sorry I don’t really understand threading so hopefully that makes sense and I understood what you said in your reply.

I remember I looked into threading a month or two ago but got intimidated and moved on to some other solution - I should definitely have another look now I have a bit of a better understanding of C#. But would you happen to know any particularly good tutorials online that might give me some further direction?

Fixed update runs fixed, but Unity occasionally skips steps, my testing shows this anyhow…

I honestly didn’t read far, but you should read the important classes text section of the unity online manual scripting unit.

I don’t say go to documentation to be rude, but sounds like you need to fit into what Unity is capable of to find success! Good luck friend! :slight_smile:

You need 60 frames each second? Or you need to make an execution 60 times per second? Because if you need 60 iterations of your update for second you can use FixedUpdate. It won’t refresh 60 times your screen per second, but it will execute 60 times the code… Well, by default exactly 50 but you can go to Edit > Settings > Time > Fixed Timestep
and change it from 0.02 seconds (50 times in a second) to 0.01666666666 (60 per second).

Not exactly. FixedUpdate can be relied on to run a specific number of times per second generally, but it doesn’t actually run those things at the times you might expect. It actually runs within the game’s update loop, it just runs more or fewer iterations of it so that it ultimately runs the correct number of times per second (while setting Time.time to the “simulated” fixed time interval). FixedUpdate is not and will never be the solution to this question.

1 Like

But the original post specifies that they do in fact need it to actually run at the specified interval exactly. That’s the whole point of the thread. They’re getting data from an Arduino light sensor, in the real world, at the moment this game gets run. If the code isn’t running at the exact times in the real world required, then the data gathered will be incorrect. FixedUpdate is just the wrong solution for this.

Threads are the answer. They need a thread dedicated to gathering data, reporting the data to a Unity class (which can pick up on the changes in the next Update cycle), and sleeping until the next cycle.

2 Likes

Unity’s frame update system as already mentioned is not designed for precise timing. The next frame is run when it can run. FixedUpdate’s precise timing is an illusion. It runs on the same main thread as much of the rest of the engine, and runs on a schedule but when nothing else is running. Unity never interrupts other code on the main thread to hit that timing. If it is time for a FixedUpdate to run, but Update is still running, FixedUpdate just waits until Update finishes, no matter how long it takes. If Update takes long enough you may see FixedUpdate run multiple times in a row to catch up. So it feels like it is running on time, when it really isn’t.

As already suggested, I’d do your precise timing on your own thread.

With Unity, remember that Unity is the main app running.

Therefore, Unity only calls your scripting code at its own convenience.

Here is some timing diagram help:

1 Like

I’d just let Unity run and use Time.time for synch. After all, you can’t display the results faster than Unity’s frame rate. Waving my hands here, but Update would ask “hey sensor, what data have you got for me”? If it spiked for 0.01 milliseconds but is now off, decide what to do. Show the time-weighted average, or alternate between the high and low values (suppose it wildly varies between X and Y, but X and Y are moving – you’d get a flicker every other frame, between the moving ends, which would give the gist). Or if you’re drawing a graph, simply add the new data.

Thanks so much for the replies everyone. The overwhelming impression I am getting is that I should really just look into threading to get the precision I need, so I will definitely do that. As I mentioned in my second post, if anyone can point me in the direction of a particularly good tutorial I would love to see it as I’m still relatively new to C# and when I’ve previously looked into threading I found the documentation and guides I was looking at a bit confusing.

I’m aware that I am pushing Unity beyond the scope of it’s intended usage, unfortunately if I’m not able to get this working then I might as well not even be using Unity and should run all of this through MATLAB or something. Unity just offers a lot of functionality I can’t get out of other applications/languages though so I am trying to make this work.

Ray is correct here, I am trying to get as much precision as I possibly can in the timing between updates. I think there was a bit of confusion in the original post - what I actually need precision for is the time between updates during which I will write information from Unity to a .csv, and I am only using the sensor as a sort of back up to ensure my timings are precise, but I think the core idea and problem associated with it remains the same.

FixedUpdate() seems like a budget solution to my problem, the idea that I can get a fixed number of updates per second is appealing but it depends on how much variability there is in the timing between updates, if it’s on the order of <10ms it would be fine but if one FixedUpdate could potentially take 100ms and then cram the remaining 59 into 900ms this would not work for me.

I had thought about pulling the computer time every 60 frames, then considering the time between each frame per second to be = (time(t) - time(t-1))/60, or just taking the timestamp from every single update but this would create a lot of nightmares for me in post-processing so it is definitely not ideal if it’s possible for me to record data at a fixed interval precisely and avoid the whole need to do manual alignment.

However Unity’s Time.time specifically is not meant to be called every frame, and as I understand it you are only supplied with the time since Awake() or Start() in seconds, so I already lose all the precision I require with that method and would need to look into other C# functions that can track time accurately down to milliseconds.