Search code examples
c#multithreadingunity-game-engineinstantiation

Unity, Calling Resources.Load from a different thread


I made a prefab to be instantiated in game.

But because I wish it to be instantiated "behind the scene", which means, create all those multiple copies of prefabs "while the player is doing something else".

So I put the code generating the prefab "in another thread".

But the Unity told me that "Load can only be called from the main thread."

I tried to move the code into a coroutine, but unfortunately coroutine runs in the "main thread"!

Or maybe I should say, they don't do multiple coroutines "parallely and concurrently"!

So could somebody please be so kind and teach me what should I do!?

Much appreciated!

Codes: (In case needed, even though I don't think it would do any good)

void Start()
{
    Thread t = new Thread(Do);

    t.Start();
}

private void Do()
{
    for(int i=0;i<1000;i++)
    {
        GameObject RaceGO = (GameObject)(Resources.Load("Race"));

        RaceGO.transform.SetParent(Content);
    }
}

Solution

  • I'm unable to test this code atm, but i guess you get the idea.

    GameObject raceGameObject;
    // Start "Message" can be a coroutine
    IEnumerator Start()
    {
        // Load the resource "Race" asynchronously
        var request = Resources.LoadAsync<GameObject>("Race");
        while(!request.IsDone) {
            yield return request;
        }
        raceGameObject = request.asset;
        Do();
    }
    
    private void Do()
    {
        // Instantiating 1000 gameobjects is nothing imo, if yes split it then, with a coroutine
        for(int i=0;i<1000;i++)
        {
            GameObject RaceGO = Instantaite(raceGameObject);
            RaceGO.transform.SetParent(Content);
        }
    }
    

    Also i do not recommend this you should just make a public Gameobject myGameObj; field assign a value to it inside the editor then just do this:

    // Assign this inside the editor
    public GameObject Race;
    
    void Start()
    {
        Do();
    }
    
    private void Do()
    {
        // Instantiating 1000 gameobjects is nothing imo, if yes split it then, with a coroutine
        for(int i=0;i<1000;i++)
        {
            GameObject RaceGO = Instantaite(Race);
            RaceGO.transform.SetParent(Content);
        }
    }