Create GameObjects in Threads?

So I have a class I’m using in Editor to make a collection of GameObjects. It takes a long time, and there’s no update in between items, so it freezes until all items are made. Wanting to speed this up, I moved the code to a separate class, and called that on a thread, but when I run it, I get an error:

Internal_CreateGameObject can only be called from the main thread.
Constructors and field initializers will be executed from the loading thread when loading a scene.
Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.

I’m wondering if there’s either
a) a means to create these objects in a thread
b) a means to update my GUI on the status between GameObject Creations (I’ve looked at Coroutine but didn’t quite get it.
c) Application.DoEvents for those familiar with VB.Net.

All Unity related objects are NOT thread safe and can either only be accessed from the main thread or will result in unexpected behavior.

You can either use a coroutine or just manage an update state yourself and chunk instantiation. Either way the implementation should look pretty much the same.

For a coroutine approach, you can do something along these lines:

IEnumerator InstantiateOverTime( GameObject prefab, int count, int frames )
{
    int itemsPerFrame = Mathf.Floor( count / frames );
    int spawned = 0;

    while ( spawned < count )
    {
        for ( int i = 0; i < itemsPerFrame && spawned < count; i++ )
        {
            Instantiate( prefab );
            spawned++;
        }

        yield return new WaitForEndOfFrame();
    }
}

What this does in essense is run the inner loop a specified number of times, once the inner loop completes it hits the yield statement, where it yields execution and returns to execute at the specified time. After returning it will evaluate the outer loop and the process will recur untill all items have been spawned.

You can also achieve the same result by implementing the same behavior inside an Update() call, only instead of the outer loop, you would evaluate if ( spawned < count ) before entering the inner loop.

  • Do note I haven’t tested this code, just writing off the top of my head as I’m having dinner. Might be some typos hiding there or an off by 1 in the math :slight_smile: