Search Unity

Question Perform Non-Destructive Methods at Build

Discussion in 'Editor & General Support' started by cassius, Jan 6, 2022.

  1. cassius

    cassius

    Joined:
    Aug 5, 2012
    Posts:
    125
    Hello,

    I have a few processes currently during the Start() method where I combine a bunch of static mesh for performance reasons, in addition to other things like instantiating auto-generated resource pools, etc. This has been fine up to now, but I'm getting closer to launching a beta and need to find a way to move the processes into a build step, which will significantly speed up my game's startup time. Right now the scene starts about 20 seconds after completing the load, whereas it takes about 3-5 seconds without these processes enabled in Start().

    How do I go about doing a CombineMeshes during the build in a way that leaves the Scene in its original state? My understanding is that the scene must be saved in the desired state so the build can be performed. However saving the scene after CombineMeshes has been executed will leave me in a very poor state for further world building, throughout the beta, final game, and expansions.

    Thank you.
     
  2. cassius

    cassius

    Joined:
    Aug 5, 2012
    Posts:
    125
    Bumping in hopes someone has an answer or suggestions.
     
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    1. Unity has the [PostProcessScene] attribute that allows you to hook into the build process for scenes. Unity calls the PostProcessScene method for each scene during build, which can be used to modify it. I used it in the past to combine meshes.

    One caveat I found specifically with combining meshes during the PostProcessScene callback is that I had to disable Unity's static batching. With static batching enabled, Unity already pre-combined things and spit out errors. This was in 2015, newer Unity versions might not have this issue anymore.

    2. I prefer what you refer to as "destructive approach". I do changes in a pre-build step, because it allows me to do much more than using Unity build callbacks. If you're using a Version Control System, such as Git or SVN, it's not destructive at all.

    Instead of using the "File > Build" button, I trigger a build via BuildPlayer instead. This allows me to perform all the optimization steps in the project and scenes before Unity is actually building the content. After the build completed, a "revert changes" via the aforementioned version control system restores the unmodified content.
     
  4. cassius

    cassius

    Joined:
    Aug 5, 2012
    Posts:
    125
    Thanks for the reply.
    I had come across this but it didn't quite seem to work as I expected it. But honestly, I didn't fully understand it based on the documentation so I've been searching online for examples on places like github and similar. Haven't yet found a way to do quite what I need yet.

    When you say you had to disable static batching, I assume you mean only for the objects whose mesh was being combined and not for the entire scene? If it's for the entire scene, this would be a non-starter for me unfortunately, though I don't see why it would be required. Perhaps in your case you were combining all objects that would be statically batched?

    Sure, though I'd still consider it destructive as one would need to revert using revision control. That would, at a minimum, force a code recompile in Unity. It's still an option, sure. But since I'm currently building about 10 times a day (though I expect that to be reduced in the coming weeks) it would be quite the hassle, even if I fully automated the build/revert pipeline.

    Here's what I'm thinking of doing, and maybe you'll know if I'm headed to a major road block :)

    First off, I use Addressables for the entire Scene.
    I'm thinking of having a "working" Scene and a "build" Scene. Basically the "working" scene is where I'd do all my world building and editor-play mode tests. Then I would save my "working" scene over the "build" scene (replacing it), which would be Addressable. Then, during the build process, it wouldn't matter as much if things were more destructive as it would only apply to the "build" scene and I'd still have my prestine "working" scene. I could then rinse and repeat this process as many times as needed without having to do any git reverts.