Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Download and save external content catalog

Discussion in 'Addressables' started by Tayfe, Feb 21, 2020.

  1. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Based on my previous thread I succeeded to load external content into my application. But now I am facing the problem to load the content from the local device when the content has been downloaded once before.

    My solution is similar to the solution from this post and works like this:
    1. InitializeAsync()
    2. LoadContentCatalogAsync()
    3. LoadResourceLocationsAsync()
    4. DownloadDependenciesAsync()
    5. LoadAssetsAsync()
    6. LoadSceneAsync()
    As said everything works fine this way. But I don't want the application to download the content on every start. Instead I expect it to download it once and check on every restart whether the content does already exist on the local device (as I thought that that's the use case of addressables).

    So how can I load the content to the local device? DownloadDependenciesAsync() sounds like this is already done but I can't find a path where the content might be saved.
    I thought maybe I do not even have to care about this and tried to skip the download part, so executing just step 1 and jump from there directly to step 5. But I just recieve an InvalidKeyException (even though the key was correct before).

    Can someone think of a solution for my problem?
     
  2. cadxplore

    cadxplore

    Joined:
    Sep 4, 2019
    Posts:
    17
    Bump. I want to ask about this too.
     
  3. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    581
    Depending on your target platform, Addressables uses the caching mechanism of that platform, if available. So the next time you load any assets, it will pull from cache if it exists, or it will fallback to download. Obviously, if the platform doesn't support caching, it will download every time. This can be disabled in group's advanced settings.

    If the platform's cache isn't good enough for you, and you want to download to an absolute path on the machine, I think you will have to handle that on your own. That can be achieved by doing a regular download of your content (not using Addressables API), then initialize Addressables with a path that points to that downloaded path.
     
  4. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Your words sound like if it's enough to start with Addressables.LoadAssetAsync<TYPE> once the content has been downloaded before. But this doesn't work for me.

    You mean GroupSettings -> Content Packing & Loading -> Advanced Options -> Use Asset Bundle Cache? This option is turned on.

    My function for loading addressables looks like this (Addressables.InitializeAsync() has been called before!):

    Code (CSharp):
    1. /// <summary>
    2.     /// Loads the addressable asset asynchronus
    3.     /// </summary>
    4.     /// <param name="name">Name of the asset</param>
    5.     /// <param name="type">Type of the asset</param>
    6.     private IEnumerator LoadAddressableAssetAsync(string name, ContentType type, bool isOfflineAvailable)
    7.     {
    8.         if(!isOfflineAvailable)
    9.         {
    10.             // Load content from catalog and wait for it
    11.             AsyncOperationHandle<IResourceLocator> handleCatalog = Addressables.LoadContentCatalogAsync(catalogPath);
    12.  
    13.             while (!handleCatalog.IsDone)
    14.             {
    15.                 yield return null;
    16.             }
    17.  
    18.             // Load location of resources and wait for it
    19.             AsyncOperationHandle<IList<IResourceLocation>> handleResource = Addressables.LoadResourceLocationsAsync("");
    20.  
    21.             while (!handleResource.IsDone)
    22.             {
    23.                 yield return null;
    24.             }
    25.  
    26.             // Save locations
    27.             List<IResourceLocation> locations = new List<IResourceLocation>(handleResource.Result);
    28.  
    29.             // Download dependencies and wait for it
    30.             AsyncOperationHandle handleDependencies = Addressables.DownloadDependenciesAsync(name);
    31.  
    32.             while (!handleDependencies.IsDone)
    33.             {
    34.                 yield return null;
    35.             }
    36.         }
    37.  
    38.         // Load the given asset depending on it's type
    39.         if (type == ContentType.SCENE)
    40.         {
    41.             // Load desired scene and wait for it
    42.             AsyncOperationHandle<Scene> handleAsset = Addressables.LoadAssetAsync<Scene>(name);
    43.  
    44.             while (!handleAsset.IsDone)
    45.             {
    46.                 yield return null;
    47.             }
    48.         }
    49.         else if (type == ContentType.GAMEOBJECT)
    50.         {
    51.             // Load desired gameobject and wait for it
    52.             AsyncOperationHandle<GameObject> handleAsset = Addressables.LoadAssetAsync<GameObject>(name);
    53.  
    54.             while (!handleAsset.IsDone)
    55.             {
    56.                 yield return null;
    57.             }
    58.         }
    59.  
    60.         yield return null;
    61.     }
     
  5. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    581
    What doesn't work? I believe
    LoadContentCatalogAsync
    will always download in the current version of Addressables. I never use
    LoadResourceLocationsAsync
    and I'm not sure how it works. But why are you even loading that and not using it? I also never use
    DownloadDependenciesAsync
    and am not sure how it works.

    In my code, I only Initialize (always downloads the catalog) then LoadAsset or LoadScene (always pulls it from the cache).

    [EDIT]
    Is your remote load path set properly?
     
  6. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18

    Did you got this to work?
     
  7. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Sadly not yet.

    Good point. I don't know what it does either. That's the copy&pasted part and I didn't realize that I don't use it. So I just removed it.

    So I've got this function now:

    Code (CSharp):
    1.     /// <summary>
    2.     /// Loads the addressable asset asynchronus
    3.     /// </summary>
    4.     /// <param name="name">Name of the asset</param>
    5.     /// <param name="type">Type of the asset</param>
    6.     private IEnumerator LoadAddressableAssetAsync(string name, ContentType type, bool isOfflineAvailable)
    7.     {
    8.         // Download asset from server if they are not locally available
    9.         if(!isOfflineAvailable)
    10.         {
    11.             // Load content from catalog and wait for it
    12.             AsyncOperationHandle<IResourceLocator> handleCatalog = Addressables.LoadContentCatalogAsync(catalogPath);
    13.  
    14.             while (!handleCatalog.IsDone)
    15.             {
    16.                 yield return null;
    17.             }
    18.  
    19.             // Download dependencies and wait for it
    20.             AsyncOperationHandle handleDependencies = Addressables.DownloadDependenciesAsync(name);
    21.  
    22.             while (!handleDependencies.IsDone)
    23.             {
    24.                 yield return null;
    25.             }
    26.         }
    27.  
    28.         // Load the given asset depending on it's type
    29.         if (type == ContentType.SCENE)
    30.         {
    31.             // Load desired scene and wait for it
    32.             AsyncOperationHandle<Scene> handleAsset = Addressables.LoadAssetAsync<Scene>(name);
    33.  
    34.             while (!handleAsset.IsDone)
    35.             {
    36.                 yield return null;
    37.             }
    38.         }
    39.         else if (type == ContentType.GAMEOBJECT)
    40.         {
    41.             // Load desired gameobject and wait for it
    42.             AsyncOperationHandle<GameObject> handleAsset = Addressables.LoadAssetAsync<GameObject>(name);
    43.  
    44.             while (!handleAsset.IsDone)
    45.             {
    46.                 yield return null;
    47.             }
    48.         }
    49.  
    50.         yield return null;
    51.     }
    Adressables are initialized in the start function and a scene is loaded within another function:

    Code (CSharp):
    1.     /// <summary>
    2.     /// Loads the given scene
    3.     /// </summary>
    4.     /// <param name="name">Name of the scene to load</param>
    5.     private void LoadScene(string name)
    6.     {
    7.         Addressables.LoadSceneAsync(name);
    8.     }
    I expect the following behaviour:

    When I start the program for the first time I want to load some asset (e.g. a scene) from the remote path and load it. For this purpose I call
    LoadAddressableAssetAsync(sceneName, ContentType.SCENE, isOfflineAvailable=false)
    . Now the scene asset should be loaded from the remote path so that I can load the scene with
    LoadScene(sceneName)
    . The functions are called in this order:
    1. InitializeAsync()
    2. LoadContentCatalogAsync()
    3. DownloadDependenciesAsync()
    4. LoadAssetsAsync()
    5. LoadSceneAsync()
    This part works fine!

    As the next step I shutdown the program and restart it. I do now expect the addressable assets to be stored in some cache since they should have been downloaded in the first run. So this time I call LoadAddressableAssetAsync(sceneName, ContentType.SCENE, isOfflineAvailable=true) and load the scene again with
    LoadScene(sceneName)
    . The functions are called in this order:
    1. InitializeAsync()
    2. LoadAssetsAsync()
    3. LoadSceneAsync()
    This is not working and that's the problem.
     
    pahe likes this.
  8. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    581
    Code (CSharp):
    1. AsyncOperationHandle<Scene> handleAsset = Addressables.LoadAssetAsync<Scene>(name);
    Code (CSharp):
    1. Addressables.LoadSceneAsync(name);
    Notice the difference between these 2? I don't think you can load a
    Scene
    through LoadAsset function. Is this not blowing up the first time you try it?
     
  9. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18

    I got this to work and only have to download it once , I have 2 buttons one runs downloadsizeasync() to check if I need to download then I run downloaddependencies with a progress bar , then the other button runs loadresourceasync and loadlevelasync , then I close the android app and run it again , this time download button prints already downloaded , and load button load the scene , even after closing the app size is increased.
     
  10. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18
    Do you want me to paste my code ?
     
  11. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18
    also we can save all levels in IResourceLocation list and use them later after they have downloaded .
     
  12. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Oh yes, please! That would help me a lot!
     
  13. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18
    Now I must warn you that I dont know if this is the proper way to do it , nonetheless it works for me , with my scene assetsbundle uploaded on AWS S3 bucket , once you select build script you can even delete the scene from editor and it will work . Mind you the progress bar is giving me issues. Once download button gives a Resource collected text you can press Load button. This will stay in your apk cache and not download again . If some one can point us to how its done correctly or just by using URL which im struggling to do please reply back asap.

    So I have two buttons :
    1- Download button
    2- Load Button

    Code for download button:

    Code (CSharp):
    1. private IEnumerator GetMeAsap() {
    2.  
    3.         AsyncOperationHandle<long> firstCheck = Addressables.GetDownloadSizeAsync(myObject);
    4.  
    5.         while (!firstCheck.IsDone)
    6.         {
    7.             textObject.text = "Checking";
    8.             yield return null;
    9.         }
    10.  
    11.         if (firstCheck.Result == 0)
    12.         {
    13.             textObject.text = "Already Downloaded";
    14.         }
    15.         else
    16.         {
    17.             textObject.text = firstCheck.Result.ToString() + " Bytes Needs to be downloaded ";
    18.         }
    19.        yield return new WaitForSeconds(2);
    20.  
    21.  
    22.         AsyncOperationHandle handleCatalog = Addressables.DownloadDependenciesAsync(myObject);
    23.  
    24.         while (!handleCatalog.IsDone)
    25.         {
    26.             mySLider.value = handleCatalog.PercentComplete* firstCheck.Result;
    27.  
    28.             yield return null;
    29.         }
    30.  
    31.         if (handleCatalog.Status == AsyncOperationStatus.Succeeded)
    32.         {
    33.  
    34.             textObject.text = "Resource Collected";
    35.         }
    36.         else
    37.         {
    38.             textObject.text = "Failed to collect resource";
    39.         }
    40.  
    41.  
    42.  
    43.  
    44.  
    45.         yield return 0;
    46.  
    47.     }
    You can get out of the function after it prints Already Downloaded , I was just testing stuff. If you want you can check the app size before and after download so yeah it only downloads once.


    Code For Load button:


    Code (CSharp):
    1. private IEnumerator LoadMe() {
    2.  
    3.  
    4.          AsyncOperationHandle < IList < IResourceLocation >> handleResource = Addressables.LoadResourceLocationsAsync(myObject);
    5.  
    6.         while (!handleResource.IsDone)
    7.         {
    8.             mySLider.value = 0;
    9.             yield return null;
    10.         }
    11.  
    12.         if (handleResource.Status == AsyncOperationStatus.Succeeded)
    13.         {
    14.             myItems = new List<IResourceLocation>(handleResource.Result);
    15.             textObject.text = "Resource Downloaded";
    16.         }
    17.         else
    18.         {
    19.             textObject.text = " All Failed ";
    20.         }
    21.  
    22.  
    23.         AsyncOperationHandle<SceneInstance> handleCatalog = Addressables.LoadSceneAsync(myObject,LoadSceneMode.Single);
    24.  
    25.             while (!handleCatalog.IsDone)
    26.             {
    27.                 mySLider.value = handleCatalog.PercentComplete;
    28.                 yield return null;
    29.             }
    30.  
    31.  
    32.  
    33.  
    34.  
    35.         yield return 0;
    36.  
    37.     }
    So turns out it never works for me if I dont run download resource location first , it will also work if you use handleResource.Result[0] if its a single scene.Resource download does not change the app size I have checked 5 times . Strange.

    Now remember the scenes loaded from addressables cannot be used with scenemanager , so when you get the result back store it in a generic or create an IResourceLocation list to save it for later or create a Label List , and when you change the level no need to unloadAsync .

    Adressable Package used 1.6 with unity 2019.3
     
    Last edited: Mar 3, 2020
  14. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18
    Hope it helps
     
  15. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Sadly not. Your code doesn't work in my case (catalog from URL). I have two buttons as well, "Download scene" and "Load scene". When I click Download first and Load second everything works fine. But after restarting the program and clicking just Load I just recieve an error at
    LoadSceneAsync()
    :

    Exception encountered in operation UnityEngine.ResourceManagement.ResourceManager+CompletedOperation`1[UnityEngine.ResourceManagement.ResourceProviders.SceneInstance], result='', status='Failed': Exception of type 'UnityEngine.AddressableAssets.InvalidKeyException' was thrown., Key=Scene3, Type=UnityEngine.ResourceManagement.ResourceProviders.SceneInstance
    UnityEngine.AddressableAssets.Addressables:LoadSceneAsync(Object, LoadSceneMode, Boolean, Int32)


    Here is the code for each of these:

    Download Scene:
    Code (CSharp):
    1. private IEnumerator DownloadScene(string name)
    2.     {
    3.         // Load content from catalog and wait for it
    4.         AsyncOperationHandle<IResourceLocator> handleCatalog = Addressables.LoadContentCatalogAsync(catalogPath);
    5.  
    6.         while (!handleCatalog.IsDone)
    7.         {
    8.             yield return null;
    9.         }
    10.  
    11.         // Download dependencies and wait for it
    12.         AsyncOperationHandle handleDependencies = Addressables.DownloadDependenciesAsync(name);
    13.  
    14.         while (!handleDependencies.IsDone)
    15.         {
    16.             yield return null;
    17.         }
    18.  
    19.         yield return null;
    20.     }
    Load Scene:
    Code (CSharp):
    1. private IEnumerator LoadScene(string name)
    2.     {
    3.         // Load resource locations and wait for it
    4.         AsyncOperationHandle<IList<IResourceLocation>> handleResource = Addressables.LoadResourceLocationsAsync(name);
    5.  
    6.         while (!handleResource.IsDone)
    7.         {
    8.             yield return null;
    9.         }
    10.  
    11.         // Load scene async and wait for it
    12.         AsyncOperationHandle<SceneInstance> handleCatalog = Addressables.LoadSceneAsync(name);
    13.  
    14.         while (!handleCatalog.IsDone)
    15.         {
    16.             yield return null;
    17.         }
    18.  
    19.         yield return 0;
    20.  
    21.     }
    I can't see any difference to your code but it's still not working?! I am using Adressable Package 1.6 with unity 2019.3 as well. But I am building for Windows Standalone. Is this maybe a problem? Or do I need some special settings for this? Maybe I should also try to build for Android just to make sure that it's not a plattform problem.

    As said the catalog was builded in another unity project and I download the catalog from AWS S3 bucket just as you do. Did you also build your catalog in another unity project? Or have you some special settings?
    It throwed indeed an error message, thanks for this! At least this error is now gone.
     
  16. simbaDraco

    simbaDraco

    Joined:
    Oct 16, 2014
    Posts:
    18
    Is catalogPath variable a URL string? I am testing code to run with URL path for S3 bucket , as soon as it work ill reply back .
     
    Last edited: Mar 5, 2020
  17. araki_yuta

    araki_yuta

    Joined:
    Jan 21, 2020
    Posts:
    14
    From my testing, I believe Addressables.LoadContentCatalogAsync(catalogPath) does both download AND load content catalog much like other apis in Addressables like LoadAssetsAsync(). When you call LoadContentCatalogAsync(catalogPath), part of api loads catalog you explicitly specify on top of your built in one.
    You might have confused its functionality with it being replacing/merging your original built in catalog catalog at with one at "catalogPath", but it doesn't seems to work like that.
    So those catalogs are treated as separate catalog by Addressables, when you restart and not call LoadContentCatalogAsync again, Addressables won't register those from "catalogPath", hence InvalidKey error.

    As with your example:
    1. InitializeAsync() <- Loads BuiltInCatalog(lets call it CatalogA)
    2. LoadContentCatalogAsync() <- Loads Other catalog (call it CatalogB)
      1. Addressables seems to merge CatalogA&CatalogB for time being
    3. DownloadDependenciesAsync()
    4. LoadAssetsAsync() <- Can load files from CatalogA&B
    5. LoadSceneAsync()
    ===Restart ===
    1. InitializeAsync() <- Loads BuiltInCatalog(CatalogA)
    2. LoadAssetsAsync() <- Can load files from CatalogA (because CatalogB is not loaded)
    3. LoadSceneAsync()

    I haven't looked into inner working of that API to be sure, but from how Addressables is built, may be it can treat the additional catalog loaded by "LoadContentCatalogAsync" much the same way as other Assets, meaning it cache the whatever catalog it loads and as long as URL is the same it shouldn't re-download it again. You can check server log if Addressables is making requests only first time or not. Though, one concern is, catalog files are not AssetBundle so it might behave differently. You may try downloading the catalog outside of the Addressables and load them with "file://local/catalogPath". UnityWebRequest should support that local file loading with file:// url.
     
  18. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Yes
    catalogPath 
    is a URL string. Yes thanks for helping! It would be awesome if we could solve the problem. I also keep trying.

    Thanks for the insights, they could help as well! I will try it as suggested with a seperate download outside Addressables and load the catalog from there.
     
  19. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    541
    Interesting, this describes perfectly my problem right now with Addressable catalogues.
    While I can download the remote catalogue, it is not stored/cached and with each restart of the app, I have to download again the catalogue or else I would only have the build in catalogue.

    My approach will now be to download the catalogue and store it somehow on the disk, so I can load that catalogue even without internet connection. What do you guys think of it?
     
  20. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    581
    How are you downloading the catalog? If you're doing it through addressables, it should be storing it in the device's cache. If you're downloading it manually, then yeah, that's how it should be done. (If you do it through UnityWebRequest, it should also store it in the device's cache, which Addressables uses under the hood.)
     
  21. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    541
    I'm using
    Addressables.LoadContentCatalogAsync(url, true);
    to update the catalogue. I would understand that it's not cached when I download it manually, but as I am not, I would expect the catalogue to be cached.

    Is it working for you correctly?
     
  22. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    541
    Did you succeed at some point with an alternative approach? I also tried to store the downloaded catalogue onto disk, but I didn't achieved to load it from there then. Also serializing the catalogue is not an option, as it can't be deserialized later again.

    I'm a bit clueless here how I should "update" my catalogue without delivering a new application or having a constant internet connection.
     
  23. zhuxianzhi

    zhuxianzhi

    Joined:
    Mar 30, 2015
    Posts:
    122
    I used a custom caching mechanism, specifically modified in AssetBundleProvider.cs, CreateWebRequest method.

    Code (CSharp):
    1.  UnityWebRequest CreateWebRequest(IResourceLocation loc)
    2.         {
    3.             var url = m_ProvideHandle.ResourceManager.TransformInternalId(loc);
    4.             if (m_Options == null)
    5.                 return UnityWebRequestAssetBundle.GetAssetBundle(url);
    6.  
    7.             var webRequest = !string.IsNullOrEmpty(m_Options.Hash)
    8.                 ? UnityWebRequestAssetBundle.GetAssetBundle(url, Hash128.Parse(m_Options.Hash), m_Options.Crc)
    9.                 : UnityWebRequestAssetBundle.GetAssetBundle(url, m_Options.Crc);
    10.  
    11.  
    12.             var filePath = Application.persistentDataPath + MyPlatformMappingService.GetPath(url);
    13.             if (!Directory.Exists(Path.GetDirectoryName(filePath)))
    14.                 Directory.CreateDirectory(Path.GetDirectoryName(filePath));
    15.             webRequest.downloadHandler = new CustomAssetBundleDownloadHandler(filePath);
    16.  
    17.             if (m_Options.Timeout > 0)
    18.                 webRequest.timeout = m_Options.Timeout;
    19.             if (m_Options.RedirectLimit > 0)
    20.                 webRequest.redirectLimit = m_Options.RedirectLimit;
    21. #if !UNITY_2019_3_OR_NEWER
    22.             webRequest.chunkedTransfer = m_Options.ChunkedTransfer;
    23. #endif
    24.             if (m_ProvideHandle.ResourceManager.CertificateHandlerInstance != null)
    25.             {
    26.                 webRequest.certificateHandler = m_ProvideHandle.ResourceManager.CertificateHandlerInstance;
    27.                 webRequest.disposeCertificateHandlerOnDispose = false;
    28.             }
    29.  
    30.             return webRequest;
    31.         }
    In the loading method, I modified the priority to read from my custom directory.
     
  24. pahe

    pahe

    Joined:
    May 10, 2011
    Posts:
    541
    And this fixed the loading of the catalogue? Or which problem does this solve? I would really like to avoid changing code of the addressables package, as those changes will always be removed when updating the package.
     
  25. zhuxianzhi

    zhuxianzhi

    Joined:
    Mar 30, 2015
    Posts:
    122
    Mainly to solve the problem of synchronous loading. Even if a resource is remote, I will first download the remote resource to a custom directory when it starts to run, and then first check whether the resource exists in the custom directory when loading.
     
  26. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103

    Sadly not yet! We decided that I should work on other problems first while waiting the addressable system to improve until we try again.

    During the mean time I programmed other parts which are finished now so that I have to deal now again with this problem. And since our other parts are finished this time I might have to deal with the problem until I can solve this. So I do still appreciate any help I can get with this!

    EDIT:

    What I understand so far that the actual content from the catalog is stored. I deleted the .bundle files belonging to the catalog from the server and it still worked. Even though it took me a freaking while to figure out where they are stored when running in the editor. But finally I found them at
    %appdata%/LocalLow/Unity/ComapnyName_ProjectName/
    . So at least there are stored local.

    Now I am facing the same probem that it seems like the catalog file itself isn't cached.
    LoadContentCatalogAsync(url)
    is trying to download the catalog every time. If there is no internet connection or the catalog isn't available on the server nothing can be loaded even though it's actually locally available. This part I don't get yet and I wonder that's more a lacking feature of the system so I should wait until it's officially fixed or I should work on a workaround myself just like you did.
     
    Last edited: May 29, 2020
    JonBFS likes this.
  27. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    I managed to got it working:

    I use a
    UnitWebRequest
    to download the catalog (json and hash file) from an URL and store them at the
    Application.PersistentDataPath
    . This has to be done once.

    From there I load the catalog using
    Code (csharp):
    1. Addressables.LoadContentCatalogAsync("file://" + Application.persistentDataPath + "/" + "catalogName.json"
    followed by
    Code (csharp):
    1. Addressables.LoadResourceLocationAsync(sceneName)
    and finally
    Code (csharp):
    1. Addressables.LoadSceneAsync(sceneName)
    .
    I am very happy I could figure this out! Sadly I run straight into my next problem: How does
    Addressables.CheckForCatalogUpdates()
    work now?

    I opened another thread for this problem to keep it a little organized.
     
    Last edited: Jun 5, 2020
  28. nchandrahas

    nchandrahas

    Joined:
    Feb 4, 2019
    Posts:
    8
    I see the updated content catalog in the persistentDataPath, but where are the actual downloaded bundles saved. I dont see them any where. I have enabled UseAssetBundleCache in group settings.
     
  29. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    It depends on the plattform your program is running on.

    Android:
    internal/Android/data/com.companyName.productName/files/UnityCache/Shared

    Android SDCard:
    sdcard/Android/data/com.companyName.productName/files/UnityCache/Shared

    Windows Build:
    %appdata%/localLow/CompanyName/ProductName/

    Windows Editor:
    %appdata%/LocalLow/Unity/ComapnyName_ProjectName/


    Please correct my if I'm wrong but I think you should be able to find the .bundle files somewhere around those locations.
     
    pahe likes this.
  30. nchandrahas

    nchandrahas

    Joined:
    Feb 4, 2019
    Posts:
    8
    I am currently playing on Mac and I see the content catalog file at "/Users⁩/currentUser/Library⁩/Application Support⁩/Company Name/" but I dont see any .bundle files.
     
  31. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Oh I'm sorry but I don't have a Mac so I have no clue what the path could be.

    But there is a quite simple trick to find it out: Since they must be stored somewhere on your PC just search for them manually. You should have the name of the .bundle files so you just search for the name and you should find them somewhere on your PC because Unity is creating a folder for each bundle file with it's name. That's what I did to find them.
     
  32. Ardito92ITA

    Ardito92ITA

    Joined:
    Apr 1, 2014
    Posts:
    37
    I've got the same problem!! Can you please post all the code fixed? <3
     
  33. Tayfe

    Tayfe

    Joined:
    Nov 21, 2011
    Posts:
    103
    Even though I coded this feature myself and it worked I found the best solution: Simply update the addressables package to at least version 1.8.3 because this feature is added from there on:
    That's what I've been looking for the whole time and I'm very happy that this feature has been added officially! Next time I should stay more up to date :)

    I think this code should work now with addressables package version 1.8.3 or above.
     
    Ardito92ITA likes this.
  34. nchandrahas

    nchandrahas

    Joined:
    Feb 4, 2019
    Posts:
    8
    I found the bundle files in Macintosh HD⁩ ▸ ⁨Users⁩ ▸ ⁨xxxxxx ▸ ⁨Library⁩ ▸ ⁨Caches⁩ ▸ ⁨Unity▸ ⁨CompanyName