3
\$\begingroup\$

I am building a big world (1000+ game objects). It takes 2s on the device. I am doing it in the background (the world is hidden until fully loaded). I have figured out that I can maintain the FPS of the active scene by switching to coroutines and making yield return null;.

The main issue is when to fire yield return null;. If I do it too often, then it will slow down the loading. If I do it too rarely, it will reduce FPS on low-end devices.

My idea is simple to detect how much milliseconds have passed since the start of the frame and fire yield return null; just after I have spent for example 12ms (to leave some time to render everything else and maintain something near 60FPS).

However, I can not find an efficient way of getting the time since frame start? Unity should have something as the async loading of assets seems to consume just right time to maintain stable FPS.

\$\endgroup\$

1 Answer 1

8
\$\begingroup\$

I'll usually use System.Diagnostics.Stopwatch for this.

IEnumerator AsyncWorkCoroutine(float millisecondBudget) {
    var watch = new System.Diagnostics.Stopwatch();
    bool workComplete = false;

    long tickBudget = (long)(System.Diagnostics.Stopwatch.Frequency
                             * millisecondBudget/1000f);

    while(workComplete == false) {
        watch.Restart();
        while((workComplete == false) && (watch.ElapsedTicks < tickBudget))
           workComplete = DoSomeWork();

        yield return null;
    }
}

But if you're willing & able to work on the bleeding edge Unity versions, you should try looking into the Job System to see if it can streamline this for you, or help you take advantage of more cores.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot. I would rather remain single threaded if I can, so Job System is not for me. \$\endgroup\$
    – Seagull
    Commented Feb 22, 2018 at 19:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .