Massive performance his when using LoadSceneAsync.

Hey everyone,

I’m working on doing an open world streaming map and am loading up the map in chunks with LoadSceneAsync.

Basically I’ve got the world sectioned out into chunks that load up when the player enters their corresponding triggers.

And my script SEEMS to be working swimmingly.

All except that when it does hit the load script I get a MASSIVE chug in performance. Like it hangs for a full second.

The profiler shows that a whopping 95% of the resources is in EarlyUpdate.UpdatePreloading.

What gives?

Here’s my script, although I don’t think it’s relevant.

public class LoadMapSection : MonoBehaviour
{
    BoxCollider myCollider;

    private void Start(){
        myCollider = gameObject.GetComponent<BoxCollider>();
    }

    void OnTriggerEnter(Collider other) {
        myCollider.size = new Vector3(myCollider.size.x * 2f, myCollider.size.y * 2f, myCollider.size.z * 2f);
        Debug.Log("Player entered loading zone");
        SceneManager.LoadSceneAsync("Testing", LoadSceneMode.Additive);
    }

    void OnTriggerExit(Collider other) {
        myCollider.size = new Vector3(myCollider.size.x * 0.5f, myCollider.size.y * 0.5f, myCollider.size.z * 0.5f);
        Debug.Log("Player left loading zone");
        SceneManager.UnloadSceneAsync("Testing");
    }
}

Is this chug because Unity is only emulating async when the game is not built because it can’t be done on preprocessor commands or something?

This really sucks. Just had it happen to me too. What version of Unity are you running? I’ve used the async API successfully in past versions with great success. Now with recent versions, it’s much slower. Using 2017 2.0p4

From what I remember the editor performance of LoadLevelASync isn’t a good way of testing as it will run differently as a standalone executable or on a mobile device.

You can also change the priority of async operations so it won’t take as much of your CPU time:

Did you test it in a built executable (on windows) or just in the editor?

Hi all. I have the same issue with async load. The lag is present both in Editor and on mobile. It seems the delay is dependent on the size of scene to load (almost empty scene loaded with no lag). It seems that async loading no async at all. Unity 2017 2.0f3.
P.S. tried Application.backgroundLoadingPriority = ThreadPriority.Low; this has no effect at all.
P.P.S it seems that it depends only on scenefile size. If all objects in he scene disabled the lag is still there.

What is consuming the time?
Take a look in the profile please! :slight_smile:

How else can we know where the spike is coming from.
If you are not absolutely sure about the results, then post the screenshots here and we can help figuring out whats going on.

(Open profiler, do the scene load, then stop the game so the spike is still visible in the profiler)

The profiler also has a Deep Profile option (enable it at the top), but note it is very intense and can create a lot of lag, but it may help break down what is creating the issue a bit more.

Any results on this matter already? I have similar problems.

Yeah, it turns out that what I guessed was exactly the issue.

Unity runs testing on preprocessor commands. Commands that can be done without compiling the scripts.

Multithreading and Asynch are not possible on preprocessor commands.

In order to see the TRUE performance you need to make a build and test on that.

1 Like

I indeed profiled on a build. But also on a build Async loading isn’t working as expected. Still trying to figure out a proper solution.

If that’s not it, I’m not entirely sure.

I’m on a trip right now. When I’m back i’ll figure out the problem and post the results.

Did you ever find a solution to this problem @Jojoba007 ? We are experiencing it in 2018.3.5f1.

2 Likes

Most likely deserialization of objects is happening on the main thread, as Unity can’t create GameObjects on any other thread (to my knowledge). So the spike will scale with the amount of content in the scene, disabled or not. Your only option is to have the individual objects inside the scene be loaded asynchronously separately. I could be wrong, but since nobody has posted a profile screenshot… It’s the most likely scenario.

For those who google this in the future:
There’s not a lot of overhead of doing LoadAsync on its own.

Also, always profile build in this case, as the editor is pretty much synchronous (faking async loading).
Which will perform drastically differently from the build.

Main concerns about performance should be in the amount of objects, resources to load, and script logic to execute.
The lesser you got, the better results will be.

By the way, from my experience, smaller sub-scenes load faster than one large one.
(More jobs involved, but it depends on the hardware you’re running)

Try splitting your scenes to more atomic chunks.

Also, there’s probably always going to be at least one sync point for the jobs to push all resources back to the main thread. Which is kinda unfortunately, but that’s what been done on native side, and there’s not much that can be done about it.

So there will be a spike no matter what you do. However, see above.
The less you’ve got to push, the lesser that spike will be.

Also, Unity - Scripting API: Application.backgroundLoadingPriority
Setting the priority to low actually yields better results for me (both performance and loading time wise).
Try it, maybe it will improve overall performance of loading for you.

2 Likes