Load a scene in background with a very time consuming script in Start() method

Hi!
I want to load a scene Async by using this code:

public class LevelLoader : MonoBehaviour
{
    public GameObject loadingScreen;
    public Slider slider;

    public void LoadLevel(int sceneIndex)
    {
        StartCoroutine(LoadAsync(sceneIndex));
    }

    IEnumerator LoadAsync(int sceneIndex)
    {
        AsyncOperation operation = SceneManager.LoadSceneAsync(sceneIndex);

        loadingScreen.SetActive(true);

        while(!operation.isDone)
        {
            float progress = Mathf.Clamp01(operation.progress / 0.9f);
            Debug.Log(progress);
            slider.value = progress;

            yield return null;
        }
    }
}

But in the scene that I’m loading there is an 2-dimensional array [512:512] that I have to fill with data and then Instantiate prefabs (512*512) in Start() method.

So… the above code is not working as I want to. Unity freezes during this Start() method, and finaly everything is loaded, but I don’t want this freeze.

Make Start a coroutine and insert some

yield return null;

in the beginning and after each row or so

2 Likes

Yeah… but this Start() method is in a script attached to an object in the scene that is about to load.
If I do like you said, it will load the scene and then instantiate prefabs. So this load screen will be visible for a fraction of a second.
I want to this whole process was made in the background.

They are saying to split up your loading and instantiating across multiple frames AND THEN hide the loading screen.

The simple truth of it is you will not be able to load and instantiate 512*512 (262144 prefabs!?!?) in one go without serious stutter, on almost any machine. So you need to do it bit by bit. So change your loading to split it over multiple frames, with a loading screen hiding it while that happens.

The instantiating part is part of the loading, you should not hide the load screen until the freeze / lock up has finished.

EDIT: just so you know, there is almost always a better way to do this than having 262144 gameobjects being spawned, each which have an overhead. Im not sure what your objects are, but almost certainly this is not the way to go about it. Every gameobject and monobehaviour incurs a performance cost, however small, and cummitavely this will add to a massive amount. Ask yourself, does everything need to be a gameobject? You can draw meshes without gameobjects, and you can hold data all on one object or scriptable objects etc etc. Most things can be combined with clever thinking, to clean up that hierarchy and reduce overhead.

1 Like

Thanks everyone!

1 Like