Multithreaded chunk loading

I am working on a chunk loading system and I am wondering if I can implement multithreading differently as I have it now. As it is set up right now only vertices and triangles of the ground mesh are created by another thread but i would like to be able to work on Unity classes like the mesh itself (since mesh.Optimize(), mesh.RecalculateNormals() etc are compute heavy) and also instantiate game objects which right now is handled by the main thread.

Can i somehow offload a “throwaway” scene or gameObject to a secondary thread and create my chunk there independent of the main thread and when it is done push that object/scene to the main thread so to instantiate it in the main scene?

The way I have done it is to load the scene to 90% then begin my map-generation and split things done only allowed to do from the main-unity-thread and the rest in my own low-priority-thread. I communicate from my thread to the main thread with an event when work is needed in the main thread before continue running.
It’s too much irrelevant code to paste here but you can look at it beginning here: galaxyvr/Assets/C#/GameLevel.cs at master · rh-galaxy/galaxyvr · GitHub

Here is my scene load code which activates the scene when GameLevel.bMapLoaded becomes true.
GameManager.cs:

//called from the main state machine in Update() like this
GameLevel.bMapLoaded = false;
StartCoroutine(LoadAsyncScene());

bool bIsMapScene = false; //else menu
bool bBeginMapLoading = false;
string szToLoad = "Scenes/PlayGame";
IEnumerator LoadAsyncScene()
{
    asyncLoad = SceneManager.LoadSceneAsync(szToLoad, LoadSceneMode.Single);
    asyncLoad.allowSceneActivation = false;

    //wait until the asynchronous scene fully loads
    while (!asyncLoad.isDone)
    {
        //scene has loaded as much as possible, the last 10% can't be multi-threaded
        if (asyncLoad.progress >= 0.9f)
        {
            bBeginMapLoading = true;
            if (bIsMapScene && GameLevel.bMapLoaded || !bIsMapScene)
                asyncLoad.allowSceneActivation = true;
        }

        yield return null;
    }
    bLoadDone = asyncLoad.isDone;
}

I tried to limit the code running in the main thread to 7ms chunks to keep fps at 90. But still ended up fading to black while loading to avoid frame freezes (make them invisible).


But to answer your question, it isn’t possible to do some things outside of the main thread. And I don’t think it’s documented which things that are forbidden. You have to try.