Search Unity

AssetDatabase.ImportPackage in Pre-Export Method

Discussion in 'Asset Database' started by headjack, Jul 27, 2016.

  1. headjack

    headjack

    Joined:
    Dec 13, 2014
    Posts:
    6
    In order to include additional content in a Cloud Build that is independent of source control, we want to import a unitypackage in the Pre-Export Method. However, AssetDatabase.ImportPackage is not a blocking operation, which means the method continues execution before the package is imported. This means the Pre-Export Method is finished and the build starts before the package content is included in the project.

    Is there any way to include a Unity Package in a Cloud Build at build time?
     
    no_me likes this.
  2. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Official Answer: None currently.

    Unofficial Answer: There is an internal api `AssetDatabase.ImportPackageImmediately(string packagePath)` that is possible to use with C# reflection to do just what you want. Disclaimer: It's internal so the api or functionality could change, remove, etc at any time. So we don't recommend or support using internal functions.
     
  3. OlafZ

    OlafZ

    Joined:
    Aug 3, 2016
    Posts:
    17
    Thanks for the Unofficial answer. I managed to use c# reflection to call ImportPackageImmediately and it does do synchronous import, however the resulting Unity Cloud Build application does not function and the build log gives multiple warnings of type:
    [Unity] Script attached to <GameObject> in scene <Prefab/Scene> is missing or no valid script is attached.
    These warnings also show up when building locally using the same build script, but do not show up when building manually, so the script references are correct, they just seem to not be resolved yet when the build starts, but get resolved after.
    I've tried just about every command I could find to refresh these references in the Pre-export script before building, but nothing works. This includes: AssetDatabase.Refresh (including any and all Import Flags) and AssetDatabase.ImportAsset on the entire Assets folder (recursive). Nothing seems to update the script references. They are updated correctly after the build script is finished, by the editor's own asset updating function that is always running in the background in the editor, but I don't know how to explicitly call that function inside of the build script.
    For the way we want to use Unity Cloud Build, we need to be able to include unity package contents (with prefabs, with script references, etc.) in the build process.

    Any help at all is greatly appreciated. Thanks in advance.
     
  4. OlafZ

    OlafZ

    Joined:
    Aug 3, 2016
    Posts:
    17
    I've attached a very simple test case for the issue I've described above. The zip contains a project and unitypackage that can be imported and build automatically by selecting the menu item "Test/Build with UnityPackage". The resulting standalone player is corrupt and there are script reference warnings during building (as my previous post describes).

    When manually importing the unitypackage and building the project, no issues occur. This suggests that the Editor does some compile/import/references resolving step that needs to be triggered by the build script (and does not happen when calling AssetDatabase.Refresh).

    Once again, any help is greatly appreciated. I understand this is a slightly unorthodox use of a build script (importing a package just before building), but it greatly simplifies our (Unity Cloud Build) workflow and would be great if possible.

    Thanks again in advance.
     

    Attached Files:

  5. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Ya, things get tricky when importing scripts. Under normal circumstances, Unity Editor runs in a loop. At the beginning of each loop, before it runs any C# code it recompiles the code if anything has changed and reloads the running code. Because of this process, it can't do this while you are executing C# code, even when using AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport). In Cloud Build, Unity is executed via command line mode to run the build, and then exit. The problem here is that the loop is basically only run once and then unity exits.

    Hmm...what might be possible is use precompiled scripts in your Unity Package. This wouldn't work with IL2CPP or AOT platforms (iOS, WebGL, Android depending on settings), but you could compile your scripts into a DLL using MonoDevelop and drop that into your unity package.
     
  6. OlafZ

    OlafZ

    Joined:
    Aug 3, 2016
    Posts:
    17
    Thank you for the quick response. That is unfortunate, but an understandable limitation. We do unfortunately want to support iOS, so combined with other considerations, precompiled scripts are likely not the right solution. We'll have to look into an alternative, by creatively using source control probably.

    Is there any chance the Unity commandline argument -importPackage <pathname> will at some point be supported by Unity Cloud Build, by supplying a web address to a unity package instead of a pathname, since a local path makes little sense with UCB?
     
  7. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    That is something I think we could support, we have also tossed around the idea of an async build pipeline so users could do something just like this via pre / post callbacks. As far as priority of features goes though, I'd suggest adding the feature to the feedback site and getting people to vote on it as that is honestly one of the best ways to tell us what you all want to see. https://feedback.unity3d.com/
     
  8. uScript

    uScript

    Joined:
    Feb 20, 2011
    Posts:
    232
    Regarding the single loop and then exit issue, I seem to have figured out a way around that. I was getting the following errors after creating a project and importing a package in separate batch file steps:

    Code (CSharp):
    1. Compile process is not finished yet. This should not happen.
    2. UnityEngine.Debug:Internal_Log(Int32, String, Object)
    3. UnityEngine.Debug:LogWarning(Object)
    4. UnityEditor.Scripting.Compilers.ScriptCompilerBase:GetCompilerMessages() (at C:\buildslave\unity\build\Editor\Mono\Scripting\Compilers\ScriptCompilerBase.cs:96)
    5. (Filename: C:/buildslave/unity/build/Editor/Mono/Scripting/Compilers/ScriptCompilerBase.cs Line: 96)
    6.  
    7. Could not fetch error messages from compilerInvalidOperationException: The process must exit before getting the requested information.
    8.   at System.Diagnostics.Process.get_ExitCode () [0x00000] in <filename unknown>:0
    9.  
    10.   at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode ()
    11.  
    12.   at UnityEditor.Utils.Program.get_ExitCode () [0x00000] in C:\buildslave\unity\build\Editor\Mono\Utils\Program.cs:104
    13.  
    14.   at UnityEditor.Scripting.Compilers.ScriptCompilerBase.CompilationHadFailure () [0x00000] in C:\buildslave\unity\build\Editor\Mono\Scripting\Compilers\ScriptCompilerBase.cs:105
    15.  
    16.   at UnityEditor.Scripting.Compilers.ScriptCompilerBase.DumpStreamOutputToLog () [0x00000] in C:\buildslave\unity\build\Editor\Mono\Scripting\Compilers\ScriptCompilerBase.cs:116
    17.  
    18.   at UnityEditor.Scripting.Compilers.ScriptCompilerBase.GetCompilerMessages () [0x00015] in C:\buildslave\unity\build\Editor\Mono\Scripting\Compilers\ScriptCompilerBase.cs:98
    19. (Filename: C:/buildslave/unity/build/Editor/Mono/Utils/Program.cs Line: 104)
    20.  
    Here are the steps I was trying to do as part of my uScript package build pipeline (all of the Unity steps also have the -quit -batchmode -nographics options):

    1. Unity.exe -createProject <name>
    2. Unity.exe -projectPath <path from step 1> -importPackage <old package path>
    3. Unity.exe -projectPath <path from step 1> [this is the step that produces the error and forces the script to stop because of a return code of 1 instead of 0]
    4. copy updated files into project from step 1 [non-Unity step]
    5. Unity.exe -projectPath <path from step 1> -exportPackage <directory to export> <new unitypackage path>

    The errors above were happening no matter what I did in that 3rd step (i.e. when I started work on this, I did not have that step 3, so it was the -exportPackage step that was producing the error). After reading your post above about the single loop and exit paradigm, I decided to try ignoring the failure return code in step 3 and letting the script continue. The result was that I could proceed on with my build process as normal after that failure. Hope this helps someone - I was stumped on this for a while.