Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Change Build Scenes Before Build

Discussion in 'Editor & General Support' started by TerabyteTim, Mar 12, 2018.

  1. TerabyteTim

    TerabyteTim

    Joined:
    Oct 20, 2011
    Posts:
    115
    I need the ability to verify a certain scene is always first in the build order. I currently can use "EditorBuildSettings.scenes" along with an "OnPreprocessBuild()" method to check the build scene order, and correct it if needed.

    Using the above method successfully modifies the build scene order so that the scene I want is first, but it seems "OnPreprocessBuild()" is actually called after the scenes for a build are compiled, meaning scene changes done in that method do not get propagated to the actual build.
    You have to rebuild after the initial build to get the modified scene order.

    Is there any way to call a function before any build functionality has executed? I would like this to work with the default "Build" button, as well as Unity Cloud Builds, which is why I need some sort of method call before the build is actually processed.

    Having an "[InitializeOnLoadMethod]"method almost works, as this works for cloud builds, but that function is not always called when the "Build" button in Unity is pressed.
    One idea I had was potentially stopping the build by logging an error, then restarting it with the same build settings so the new scene order is maintained. Is there any way to get the current build settings of a running build? So I can ensure my new "BuildPipeline.BuildPlayer()" call uses all the same properties from the previous build.
     
    LazloBonin likes this.
  2. Antony-Blackett

    Antony-Blackett

    Joined:
    Feb 15, 2011
    Posts:
    1,772
    Did you find a solution for this?

    I'm processing my scenes and would like to copy my scenes to a BuildScenes, modify the scenes in the build to point to the new scenes and then build using them, afterwards i switch back to the original scenes.

    I do this because there are editing tools and data in my scenes that can be stripped out for the build to device.

    I could copy the original scenes somewhere, and overwrite them with the processed versions and not touch the EditorBuildSettings.scenes but I've done this is previous projects and occasionally when a build fails halfway or Unity crashes for some reason you end up with messed up scenes and you have to revert from version control or copy them back manually.
     
  3. darbotron

    darbotron

    Joined:
    Aug 9, 2010
    Posts:
    351
    I've just needed this too...

    Would be lovely to get a callback in time to validate EditorBuildSettings.scenes before the build is pre-processed but I couldn't find one.

    I do as OP suggested:
    1. hook into the PreProcessBuild (https://docs.unity3d.com/ScriptReference/Build.IPreprocessBuildWithReport.OnPreprocessBuild.html)
    2. do validation on EditorBuildSettings.scenes
      (https://docs.unity3d.com/ScriptReference/EditorBuildSettings-scenes.html)
    3. If validation requires a fix I use Debug.LogError() to force the build to fail with a message telling the user why it failed
    4. if the issue can be corrected in script (which all of mine can) you can simply fix the issue and inform the user that the error was handled and that the build should now work on a re-try
    It's not an ideal solution, but this stops the build very quickly when it fails validation (almost instantly in my test project) so it shouldn't be too bad.

    If this was for an automated build process you could check the error log for a specific string you write on validation error and re-try.
     
    LazloBonin likes this.
  4. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    I would also love a solution to this!
     
  5. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,946
    It's not foolproof because you can circumvent it, but in theory you can use a custom build method for this:
    https://docs.unity3d.com/ScriptReference/BuildPipeline.BuildPlayer.html

    So basically do whatever you see fit before you call the build process. But you can read the Build Settings from the built-in settings window through this.
     
    CodeSmile likes this.
  6. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    Right, thanks for the workaround suggestion, but I'm looking for something that would work with the File>Build dialog.
     
  7. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,946
    CodeSmile, NibbleByte3 and LazloBonin like this.
  8. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
  9. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,946
    Yes, according to the description on the linked page:
     
    LazloBonin likes this.
  10. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    Sorry, I skimmed too fast. Thanks again.
     
    Lurking-Ninja likes this.
  11. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,946
    No worries!

    So, sorry, I have never implemented this, but based on what I read, you basically make a custom build method like in my first suggestion and then you can override the default build buttons in the Build Settings Window make them call your own solution. So you will need to process the build options, added scene list and everything. But it gives great freedom to do the build whatever way you like. (If it works properly, since I never tried it :))
     
  12. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    Just want to confirm that I tested it and it works. I'm able to modify the scene list before build using BuildPlayerWindow and it works regardless of how I build locally (File > Build and Run, or File > Build Settings and then either button).

    Code (CSharp):
    1.     [InitializeOnLoad]
    2.     public static class PreBuilder
    3.     {
    4.         static PreBuilder()
    5.         {
    6.             BuildPlayerWindow.RegisterBuildPlayerHandler(OnClickBuildPlayer);
    7.         }
    8.  
    9.         private static void OnClickBuildPlayer(BuildPlayerOptions options)
    10.         {
    11.             PreBuild();
    12.             options.scenes = EditorBuildSettings.scenes.Select(ebss => ebss.path).ToArray();
    13.             BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(options);
    14.         }
    15.     }
    The only tricky thing is that if your "PreBuild()" method modifies EditorBuildSettings.scenes, you have to reassign those to your options in the build player handler before calling the default build method.

    I haven't tested UCB implementation yet but from early experiments I think it'll work by using a pre-export method, which gets called before the player builds at all:
    https://docs.unity3d.com/Manual/UnityCloudBuildPreAndPostExportMethods.html
     
  13. TerabyteTim

    TerabyteTim

    Joined:
    Oct 20, 2011
    Posts:
    115
    Sorry, just seeing this now! All of the above is correct for the latest Unity, you can use this hook to enforce project settings or scenes for the build.

    If you have any other questions feel free to ask!
     
  14. cmersereau

    cmersereau

    Joined:
    Nov 6, 2020
    Posts:
    52
    Have you confirmed a working method that integrates with UCB?
     
  15. TerabyteTim

    TerabyteTim

    Joined:
    Oct 20, 2011
    Posts:
    115
    You should be able to use the pre-export method linked
     
  16. cmersereau

    cmersereau

    Joined:
    Nov 6, 2020
    Posts:
    52
    Just wanted to confirm someone had done it before testing it myself. As you may know, testing cloud build implementations can be a very slow process so it would be nicer to know someone has actually changed the scene list using a pre-export method and it's not a theory.
     
  17. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    I can confirm the Pre and Post Export Methods for UCB work, we've been using them for months now.

    Basically, the foolproof combination seems to be:
    • Have a common PreBuild() method
    • Register it for editor builds with RegisterBuildPlayerHandler
    • Register it for UCB builds with a Pre-Export method
     
    CodeSmile and cmersereau like this.
  18. NibbleByte3

    NibbleByte3

    Joined:
    Aug 9, 2017
    Posts:
    77
    https://forum.unity.com/threads/change-build-scenes-before-build.521486/


    Just stumbled on your post and RegisterBuildPlayerHandler. If you only modify the included scenes in the build, you can use https://docs.unity3d.com/ScriptReference/BuildPlayerWindow.RegisterGetBuildPlayerOptionsHandler.html instead.
    Usage has some quirks, here is a sample:
    Code (CSharp):
    1.     [InitializeOnLoad]
    2.    public static class BuildPlayerWindowHook
    3.    {
    4.        static BuildPlayerWindowHook()
    5.        {
    6.            BuildPlayerWindow.RegisterGetBuildPlayerOptionsHandler(ProcessBuildOptions);
    7.        }
    8.  
    9.        private static BuildPlayerOptions ProcessBuildOptions(BuildPlayerOptions options)
    10.        {
    11.            // "options" are empty. Fill them in by calling the default getter.
    12.            // NOTE: this will open a dialog where the user can select the location of the build to be made.
    13.            options = BuildPlayerWindow.DefaultBuildMethods.GetBuildPlayerOptions(options);
    14.  
    15.            // "options" are now filled with the default data, including all the EditorBuildSettings.scenes.
    16.            options.scenes = new string[] { options.scenes[0] }; // Modify the scenes to your liking...
    17.  
    18.            return options;
    19.        }
    20.    }
     
    MatudaGames likes this.