Search Unity

Question Importing mesh at runtime

Discussion in 'Scripting' started by matteobesenzoni, Sep 6, 2022.

  1. matteobesenzoni

    matteobesenzoni

    Joined:
    Feb 11, 2020
    Posts:
    2
    I've been tasked to improve the performance of a plugin that imports 3D models from a proprietary format at runtime. I have yet to tackle the thousands of lines of code that currently achieve the task but very slowly.
    I'm wondering if there are some guidelines that describe how to properly generate hundreds of GameObjects with the corresponding meshes and hierarchy.
    Right now, as the file containing the 3D model is being read, every time a new node, mesh or light is found, a new GameObject is created with the necessary information, resulting in the model appearing piece by piece and the application slowing down considerably.
    I couldn't find anything similar, but does Unity have allows for the creation of multiple GameObject in batch?

    As a side note, I'm aware of Unity job system but I believe I need to re-structure the code before introducing it.

    Any help is appreciated.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Unfortunately what you need isn't something that can meaningfully benefit from threading, as the Unity API can only be used from the main thread. There might be some way with the Jobs system but I am not familiar enough with what it can do to speak to either if it is possible or if it would give a benefit.

    This must mean you are already doing this in chunks, perhaps with a coroutine??

    One piece of advice I can offer is if you have a bazillion GameObjects to make, my testing years ago indicated that it was faster to slice that work into X frames of work, yielding with a coroutine periodically, than to stack all bazillion at once.

    In other words, I found that making 1000 objects each frame for 10 frames was still faster than making 10000 total objects in one frame. That felt like an optimization gone wrong in Unity, or perhaps I had a bug in my code, plus I have no idea if it even holds true today.

    But it would still have the issue you see of partial pieces becoming visible.

    Obviously the one-and-done way is to cover up with a LOADING screen at the start, then reveal it once all your loading is done.
     
  3. matteobesenzoni

    matteobesenzoni

    Joined:
    Feb 11, 2020
    Posts:
    2
    First of all thank you for the information, it already gives me an idea of what can be achieved and what should be avoided.

    When you mention that the Unity API is only accessible from the main thread, does that include anything Unity related? I imagined only calls that modify the current state of the scene would need to be on the main thread, such as creating new GameObjects or modifying an existing one. Does creating a new component also require to be on the main thread (i.e. creating a MeshRenderer)? I still struggle to find meaningful information in the Unity documentation in regard to how the api handles this kind of situations.

    Spreading the creation of multiple GameObjects in different frames is something I was already planning as it should at least allow the application to run smoothly while loading the model, but as you already mentioned there needs to be some sort of loading feedback for very big models.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    Pretty sure it is just about everything. Debug.Log() seems safe from threads however... but don't quote me on that.

    Let me caution you further to timebox it because quite often what you seek isn't easy to actually achieve in the general "handle any data I throw at it" sense. It's always easier from an engineering standpoint to throw up a loading screen, focus 100% on loading the new stuff, then continue. The price of further engineering goes up sharply after that.