How to pause execution until function terminates
I am writing a game/program which every few seconds has to write a lot of data to the hard disk - this takes a few seconds to complete, and naturally causes the game to hang for that duration.
However, when the game resumes after the writes have completed, the game skips a few frames.
I need it that Unity will skip absolutely no frames what so ever. How can I force the Unity Engine to stop executing until the writing has fully completed, so that when it resumes, no frames have been skipped?
Context:
To provide some context, I am capturing a screenshot every frame, storing them as Texture2Ds in a queue. When the queue has more than 100 frames worth of Texture2Ds in it, I am writing the to the disk as PNGs, and clearing the queue.
I want to pause rendering/execution whilst the writing takes place so that the output (alone) is seamless.
The engine does not skip frames. it's just that the time runs on and every time dependent task is jumping by that large delta time. I think you can do one of the following:
create a class or coroutine you pass your bundle in that writes them one or two or three at a time
create another thread doing the writing
have your own time variable everything depends on that does not get increased by the full delta time when writing files
thinking about it, I'd do the threading
hexagonius, this was a great reply, thank you. In the end, I have implemented a coroutine for writing every frame. Unity handily has Time.captureFramerate, which is perfect for preventing the game from advancing until the write has finished.
Answer by StardustMotion · Dec 14, 2020 at 12:18 PM
@bhayward_incrowd I believe I had the same problem as you and found a workaround. For my personal project, I had to screenshot a high quality (~2048x4096 pixels) 360° view of the player's camera at least 30 times/second in order to make a Unity 360° video. That's very expensive and impossible to produce in real-time on my computer. So Unity freezes while writing the screenshot, and resumes then, with some frames skipped...
To fix this : Edit > Project Settings > Time And set "Maximum allowed timestep" to the same value as Fixed Timestep. What Maximum allowed timestep does is that, when your FPS becomes so garbage that you can't render every frame without having a smooth experience, Unity will skip some frames instead, depending on "Maximum allowed timestep" value.
If, like me, you need to collect every single frame, at the cost of a very slow game (x0.1-ish), proceed as above. For making pre-rendered videos, where quality > game speed it's great.
For actually interactive video games, it's bad ; you're better off with 1.0x speed and skip some frames.