Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Addressables.LoadContentCatalogAsync Freezes Cloud-Built App

Discussion in 'Addressables' started by JonathanBartel, Feb 13, 2020.

  1. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
    To expand on the title, in my project there's a block of code that is essentially this:

    Code (CSharp):
    1. public static IEnumerator LoadCatalog(string catalogPath)
    2. {
    3.     Debug.Log($"Loading catalog... ({File.Exists(catalogPath)})");
    4.  
    5.     var loadCat = Addressables.LoadContentCatalogAsync(catalogPath);
    6.     while (!loadCat.IsDone) yield return null;
    7.  
    8.     Debug.Log("Catalog loaded.");
    9. }
    This code works in the editor and also when I do a local build. Additionally, I've built this for iOS and for PC; both work fine. However, when I build through Unity Cloud Build, the resulting app hangs on LoadContentCatalogAsync. I can tell from the Debug that (1) the catalog exists and (2) the app is not reaching the second Debug line.

    I had working cloud builds when I was using AssetBundles, but have been hung up on this one line since switching to Addressables, hence why I'm posting on this forum instead of the Unity Cloud Build forum, but I can move the question if necessary.

    I'm working with Unity 2019.3.0f6 and with Addressables 1.6.0. Thanks for any help.
     
  2. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    583
    Just curious, does it work if you do
    loadCat.Completed += op => Debug.Log(op.Status);
    ? And what does that print?
     
  3. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
    @ProtoTerminator
    Per your suggestion, I added your line to my code:
    Code (CSharp):
    1. public static IEnumerator LoadCatalog(string catalogPath)
    2. {
    3.     Debug.Log($"Loading catalog... ({File.Exists(catalogPath)})");
    4.  
    5.     var loadCat = Addressables.LoadContentCatalogAsync(catalogPath);
    6.     loadCat.Completed += op => Debug.Log(op.Status);
    7.     while (!loadCat.IsDone) yield return null;
    8.  
    9.     Debug.Log("Catalog loaded.");
    10. }
    This gave me the following output in the editor and with local build:
    Code (CSharp):
    1. Loading catalog... (True)
    2. Succeeded
    3. Catalog loaded.
    With the cloud build, I get:
    Code (CSharp):
    1. Loading catalog... (True)
    ...and it hangs there.
     
    Last edited: Feb 14, 2020
  4. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    583
    Hm, would you mind posting your build script?
     
  5. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
    As far as I'm aware, I don't have a build script. Or at least I never made one. I inherited this project from someone else and I don't see any scripts in the project that look like build scripts.

    (Edit: I should clarify that I inherited this project about a year ago and have had many successful builds up until now when I introduced Addressables into the project.)
     
  6. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
  7. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    583
    Oh, are you building the addressables separately, uploading them somewhere, then running the engine build? That would make sense why it doesn't work. I build the addressables as part of my build script before the engine build so that it will work whether I run it locally or on the build server.
     
  8. Jribs

    Jribs

    Joined:
    Jun 10, 2014
    Posts:
    154
    @ProtoTerminator would you mind sharing your build script for the build server?
     
  9. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    583
    Sure. So what I do here is build the addressables to a folder outside of Assets like they recommend, then I compress the output with gzip, then I move the entire thing to StreamingAssets, then I build the engine.
    So, obviously this does a full build every time, rather than simply updating an existing build, so it's not as efficient as it could be, depending what you need to do.

    Keep in mind that, with this code in particular, the
    Application.streamingAssetsPath + "/AssetBundles"
    must not already exist.

    Code (CSharp):
    1. [MenuItem("Build/Build WebGL")]
    2. static void BuildWebGL()
    3. {
    4.     // Build addressables
    5.     UnityEditor.AddressableAssets.Settings.AddressableAssetSettings.BuildPlayerContent();
    6.     DirectoryInfo addressablesDir = new DirectoryInfo(Application.dataPath.Replace("Assets", "AssetBundles"));
    7.     Compress(addressablesDir);
    8.     addressablesDir.MoveTo(Application.streamingAssetsPath + "/AssetBundles");
    9.  
    10.     PlayerSettings.WebGL.linkerTarget = WebGLLinkerTarget.Wasm;
    11.     PlayerSettings.WebGL.wasmStreaming = true;
    12.     BuildPlayerOptions buildPlayerOptions = new BuildPlayerOptions()
    13.     {
    14.         scenes = new[] { "Assets/Scenes/init.unity" },
    15.         locationPathName = $"Builds/{projectName}",
    16.         target = BuildTarget.WebGL,
    17.         options = BuildOptions.None
    18.     };
    19.  
    20.     BuildReport report = BuildPipeline.BuildPlayer(buildPlayerOptions);
    21.     BuildSummary summary = report.summary;
    22.  
    23.     if (summary.result == BuildResult.Succeeded)
    24.     {
    25.         Debug.Log("Build succeeded: " + summary.totalSize + " bytes");
    26.     }
    27.     else if (summary.result == BuildResult.Failed)
    28.     {
    29.         Debug.Log("Build failed");
    30.     }
    31. }
     
    davidla_unity likes this.
  10. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
    Thank you very much for the detailed response! I'll give this a shot hopefully today.
     
  11. JonathanBartel

    JonathanBartel

    Joined:
    Jun 24, 2019
    Posts:
    45
    Success!!!

    @ProtoTerminator Your advice steered me in the right direction, but since my solution had to be a little different, I'm going to detail it here for the sake of others.

    As I've discovered over the course of this thread, Addressables keeps some platform-specific files in the Library folder of your project outside of the Assets folder. When building locally, it copies these files into the StreamingAssets folder and then deletes them after the build. This way, your program can build for multiple platforms without you worrying about conflicting files. However, since Unity Cloud Build does not have access to your Library folder, it cannot copy these files for you.

    What I essentially did is manually copy the folder Library/com.unity.addressables/StreamingAssetsCopy/aa into my Assets/StreamingAssets folder and push my changes up to the cloud using Unity Collaborate. This gave me a build that worked.

    It's important to note that building locally will delete that folder out of StreamingAssets again, so I will have to repeat this process every time I build from the cloud. I'll probably end up writing an editor module that does this whole copy process and then starts the cloud build from within the editor, but one step at a time.

    Thanks for your help, @ProtoTerminator. If anyone needs me to explain this better or differently, let me know.
     
    aldoginting likes this.