Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct here to familiarize yourself with the rules and how to post constructively.

  2. Unity 2022.1 is now available as the latest Tech release.
    Dismiss Notice
  3. Improve your project's performance with our new guide on profiling in Unity.
    Dismiss Notice

Bug (Case 1387523) Building player in batch mode is failed due to "A script reload is pending" error

Discussion in '2022.1 Beta' started by Kichang-Kim, Dec 10, 2021.

  1. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    Hi. I found that Unity 2022.1.0b1 is failed to build player in batch mode. In editor mode, no issue.

    Here is error message:
    Error building Player: A script reload is pending. Allow scripts to reload before building.

    Same script works without any problems on Unity 2021.x.

    Reported as Case 1387523.
     
    DrSeltsam likes this.
  2. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    It may be occurred by this:

    This totally breaks automated build pipelines. Please revert it. Or add options for replacing scripting defines to BuildPlayerOption struct, not extra (add) only.
     
  3. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    Hi @Kichang-Kim,

    this is tricky. We've had a long discussion with the scripting team about this, but ultimately will keep the current restriction in place (and make additional changes to make the error message more descriptive, and to make this behavior consistent between batchmode and UI mode). Why are we doing this? It was previously possible to build players with scripts which don't match the scripts currently loaded into the editor domain. This could cause the serialization data written out for the player not to match the data expected by the player, causing corrupted player builds in unpredictable ways.

    There are different ways around this - make your CI script invoke the editor twice, make your build script survive domain reloads using a ScriptableSingleton - but in your case, the simplest solution is likely to use `BuildPlayerOptions.extraScriptingDefines`. You can actually use that to replace scripting defines, like this:

    Code (CSharp):
    1. options.extraScriptingDefines = new[] { "MY_TEST_DEFINE=0" };
     
  4. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    Thanks for detailed reply.

    I tested your solution, MY_TEST_DEFINE=0, but it does not work on Unity 2021.2.7f1. It still defined on final build. Does it work only on Unity 2022.1b?

    Edited : Adding extra symbol "XXX=0" does not work on both 2021.2.7 and 2022.1.0b2.
     
    Last edited: Jan 11, 2022
  5. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    I'm sorry, you are right. I had tested my code before posting, but I did not realize that the C# compiler (unlike C++) would ignore defines set like that (and my original define was set to MY_TEST_DEFINE=1, so also ignored, so it looked like it worked).

    So, here's some other suggestions:
    -Don't set the defines you want as project defines, always specify them when building (or use #if UNITY_EDITOR)
    -Use build scripts which allow for multiple script invocations
    -Have stuff like this in your code:
    Code (CSharp):
    1. #if MY_DISABLE_DEFINE
    2. #undef MY_DEFINE
    3. #endif
     
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,249
    This is what we're doing in our build pipeline, is this not going to work anymore?
    Code (CSharp):
    1. PlayerSettings.SetScriptingDefineSymbolsForGroup(targetGroup, scriptingDefines);
    2. BuildPipeline.BuildPlayer(buildPlayerOptions);
    When you say "extraScriptingDefines", are these added on top of the existing defines in PlayerSettings? Is there a way to replace the current defines in PlayerSettings for a build?
     
  7. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    What means this? Is it different to executing editor twice?
     
  8. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    Yes. It already not work in Unity 2022.1b. So you can't build player with different (replaced or removed) build symbols from script. The only way is executing Unity twice, one for calling PlayerSettings.SetScriptingDefineSymbolsForGroup() and second for BuildPipeline.BuildPlayer() in CI pipeline.

    In editor (without CI), there is no way for implementing simple build script. (sadly)
     
    Peter77 likes this.
  9. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,249
    Thank you for the answer. This will break our build pipeline / build server then as well.

    BuildPlayerOptions.extraScriptingDefines
    looks like it could solve the problem for us, if it also allows to replace defines for a build and not only add new ones on top. Crossing fingers it's possible :)
     
  10. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    Either executing the editor twice, or build a build script which can continue after domain reload happens by using a ScriptableSingleton. (Yes, both options are not really convenient, but neither is building corrupted players).

    This API can only add new defines. Currently considering if we need to add a `BuildPlayerOptions.withoutScriptingDefines` API.
     
  11. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,249
    Thank you for the reply.

    Here are some thoughts: What if you rename
    extraScriptingDefines
    to just
    scriptingDefines
    but pre-polulate it with the current defines from Player Settings. With "current defines" I mean the defines that exist where the "extra" ones get added to.

    This allows us to read what scripting defines exist, add new ones and remove existing from the list as we like. It could be easier to use as well, because we only have to deal with scriptingDefines instead of extraScriptingDefines and withoutScriptingDefines and whatever might come next.

    What do you think?
     
    DrSeltsam and Kichang-Kim like this.
  12. DrSeltsam

    DrSeltsam

    Joined:
    Jul 24, 2019
    Posts:
    91
    We're also affected by this change unfortunately, preventing us from updating to 2022.1 (because we heavily rely on our automated build pipeline)...

    If setting defines through the "extraScriptingDefines" really avoids this issue, having a way to remove defines could do the trick in our case. A "withoutScriptingDefines" API would be appreciated, although a general "scriptingDefines" property (as suggested by @Peter77 ) would be a bit cleaner IMO.
     
  13. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,813
    We have been executing the editor twice forever because Unity just breaks if we try to set settings and then build.

    That is, of course, somewhat slower than just executing the editor once. It also means that we have to add build complexity to TeamCity instead of a C# build script. C# Is a lot easier to write than TeamCity settings!
    So I would love to have a build script that survives domain reload, but I don't get what you mean by using a ScriptableSingleton? What we need to do is to have a way to:

    - run some code that triggers a domain reload (and other reloads) as a side-effect of changing flags and other settings
    - wait for the reload
    - run more code.

    I don't quite understand how a thing that stores editor state between reloads helps us do that? The editor state was never the problem, the problem is that running Unity in batch mode only executes a single static method, and that single static method can't keep running across domain reloads. Or am I missing something?
     
    Last edited: Jan 17, 2022
    Kichang-Kim likes this.
  14. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    An update on this:

    We will likely be able to remove the restriction again and allow changing defines and then make a build. The define change will only affect player assemblies (since we cannot do a domain reload in the same build step), and if the define change changes serialization layout between player and editor we will detect that and fail the build.
     
    DrSeltsam and Kichang-Kim like this.
  15. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    It is not super straightforward, but you can use a SerializedSingleton to do something which causes a domain reload, store the state of your script in public fields of the SerializedSingleton, and the the OnEnable method of the SerializedSingleton will be called after domain reload when the SerializedSingleton is recreated, so you can resume your script from there. This requires that you don't call the editor command line with -quit, as that will not give you a chance to resume after domain reload. Instead you need to call Application.Exit from your build script.
     
    Baste likes this.
  16. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    5,813
    Ah, okay, replacing -quit with Application.Exit was the stage I was missing, thanks! Somewhat obvious now that you mention it :p
     
  17. DrSeltsam

    DrSeltsam

    Joined:
    Jul 24, 2019
    Posts:
    91
    I haven't tried the recent betas yet, but does this issue still persist or has this restriction already been removed in the meantime?
     
  18. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    2022.1.0b9 still has the issue.
     
    DrSeltsam likes this.
  19. DrSeltsam

    DrSeltsam

    Joined:
    Jul 24, 2019
    Posts:
    91
    Thanks for the update @Kichang-Kim !

    Is there maybe an ETA about when the changes mentioned above (either a removal of the new restriction or a way to remove scripting defines) get implemented @jonas-echterhoff ? Will they make it into the tech stream release of 2022.1?
     
  20. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,664
    Hey @DrSeltsam . This change (removing restrictions) has landed in 2022.2.0a4. I will make sure it gets backported to 22.1.
     
    DrSeltsam likes this.
  21. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    744
    I recently implemented a build runner that survives domain reloads in my build framework Trimmer, for people who want a reference:
    https://github.com/sttz/trimmer/blob/master/Editor/BuildRunner.cs

    I was already using
    extraScriptingDefines
    and implemented the runner for switching the active build target between builds, due to various issues related to conditionally-compiled build code that would not run when the active and actual build targets don't match. But the principle could be adapted to change scripting defines in addition to changing the active build target.

    You don't necessarily need to use
    ScriptableSingleton
    , any scriptable object instance can be used when you set the proper hide flags. The difficulty is that you cannot use types not supported by Unity's serialization, so any delegates are out. I worked around this by using an interface that can be implemented by other scriptable objects (that also need to be able to survive domain reloads).
     
  22. Kichang-Kim

    Kichang-Kim

    Joined:
    Oct 19, 2010
    Posts:
    807
    I checked Unity 2022.1.0b15 and it still has the issue. Will this be fixed before releasing 2022.1.0f1?

    @jonas-echterhoff
     
    Last edited: Apr 14, 2022
  23. LeonhardP

    LeonhardP

    Unity Technologies

    Joined:
    Jul 4, 2016
    Posts:
    2,971
    Kichang-Kim likes this.
  24. TG1980

    TG1980

    Joined:
    Oct 23, 2013
    Posts:
    40
    Shouldn’t you delay the release then? I mean why deliberately break everyone’s build servers by going live with such an issue? This can happen in betas but not "stable" versions. So weird as you already have a fix for it… just delay the release until the clear blockers are fixed or you will be wasting many people’s time.
     
unityunity