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

how to check if an adressable asset or scene is in cache after a download?

Discussion in 'Addressables' started by almertineshop, Apr 8, 2019.

Thread Status:
Not open for further replies.
  1. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    What i'm trying to do is to activate a play button if the addressable scene is already downloaded and in cache, and a download button if it is not in cache so that the player won't download the addressable from server everytime he wants to play the scene.

    I tried using Caching.IsVersionCached to check the bundle is in the cache using the bundle name but the problem here is that the name is not a good reference since in the addressable system I load the scene using Addressable.loadscene which loads the scene directly without giving any reference to the asset bundle. so the question is how to check if the scene is cached?

    Here is what I tried with but it is not working since I already know that the asset bundle name won't be the good reference at least in this example.

    Code (CSharp):
    1.  private IEnumerator LoadRoutine()
    2.     {
    3.  
    4.  
    5.  
    6.         var lastHash = PlayerPrefs.GetString(LAST_HASH);
    7.  
    8.         if (Caching.IsVersionCached(AssetBundleHavingTheScene.name, Hash128.Parse(lastHash)))
    9.         {
    10.  
    11.             Debug.Log("The Bundle is Cached i'll launch it");
    12.  
    13.             Addressables.LoadScene(AddressableScene);
    14.  
    15.  
    16.         }
    17.  
    18.  
    19.         else
    20.         {
    21.             Debug.Log("Not Cached I'm going to download it");
    22.  
    23.  
    24.  
    25.  
    26.             var async = Addressables.LoadScene(AddressableScene);
    27.  
    28.  
    29.             while (!async.IsDone)
    30.             {
    31.  
    32.                 ProgressNumber.text = (async.PercentComplete * 100f).ToString("F0") + ("%");
    33.                 ProgressSlider.value = async.PercentComplete;
    34.  
    35.                 Debug.Log(async.PercentComplete);
    36.                 yield return null;
    37.             }
    38.  
    39.             // At this point the scene is loaded and referenced in async.Result
    40.             Debug.Log("LOADED!");
    41.  
    42.             Scene myScene = async.Result;
    43.  
    44.  
    45.  
    46.  
    47.         }
    48.  
    49.  
    50.     }
     
    unitypro_Vidteq likes this.
  2. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    I would recommend `Addressables.GetDownloadSize(AddressableScene)`. There are a few bugs with how exactly that interacts with the cache in 0.6.8, but in the upcoming 0.7.x, they should be fixed. With that, you can check if the download size is 0 or not, and go from there (0 means cached).
     
  3. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    Thanks for your reply, I was stuck with this for over ten days now and just moved to other things while hoping I can figure a solution later. I will try that and give you some feedback later. thanks again for the reply.
     
    unity_bill likes this.
  4. bruno_1308

    bruno_1308

    Joined:
    May 16, 2018
    Posts:
    14
    Hey @almertineshop, did that work for you?
    Playing in Virtual or Packed Play mode always gives me Download size != 0, even after I call LoadScene or DownloadDependencies for a scene. It seems like it's not caching after it downloads so my if statement always enter the else part:

    Code (CSharp):
    1.  
    2. async void PressedPlay() {
    3.     // This calls GetDownloadSize under the hood and compares with 0
    4.     if (await _sceneLoader.IsSceneDownloaded(sceneName))
    5.     {
    6.         PlayTour();
    7.     }
    8.     else
    9.     {
    10.          // DownloadScene calls LoadScene under the hood, I want the player to Press Play again and my If to be true next time
    11.         SceneLoadResult result = _sceneLoader.DownloadScene(sceneName, () =>
    12.         {
    13.             // Set UI for not downloading anymore (AsyncOperationHandle completion callback)
    14.         });
    15.         // Setup UI for downloading bar progress
    16.     }
    17. }
    18.  
     
  5. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    Hi, I also had download size at 0, I tried to have a comparison of the size by comparing the download size "long" but I couldn't since the long couldn't be compared in an if statement. it seemed a little bit confusing, I tried updating to addressables system version 0.75 but I had errors showing with the IAsyncoperation i downgraded again to 0.68, but still not solved the hole download size and figuring if the download is cached issue..
     
  6. bruno_1308

    bruno_1308

    Joined:
    May 16, 2018
    Posts:
    14
    I think my problem is different: remote assets always show with download size != 0, even if after I Load them (which I supposed should cache them and then return their download size as 0)
     
  7. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    I'm not sure how reliable that interface will be in Virtual mode. For packed play mode it should work. Perhaps you are not waiting for the AsyncOperationHandle returned from GetDownloadSizeAsync to complete? Or we have a bug in the system. Opening a ticket against Unity with a sample project may help us get to the bottom of this.
     
  8. TheRealMajorGonzo

    TheRealMajorGonzo

    Joined:
    May 12, 2018
    Posts:
    12
    Not trying to necro this, but an unnamed search engine provided this as one of the first results, so I'm going to update the answer, because, obviously, I had this same question. This solution might not have existed at the time of this original question, but for my weapon loader, this works:
    Code (CSharp):
    1.        
    2. public void EquipWeaponAsset(AssetReference weaponAsset){
    3.       Debug.Log("Loading weapon asset " + weaponAsset);
    4.       if (weaponAsset.Asset){
    5.           Debug.Log("weaponAsset " + weaponAsset + " is already loaded: " + weaponAsset.Asset);
    6.           EquipWeapon((Weapon)weaponAsset.Asset);
    7.       }else{
    8.           Debug.Log("weaponAsset " + weaponAsset + " isn't yet loaded...loading");
    9.           weaponAsset.LoadAssetAsync<Weapon>().Completed += EquipWeaponAssetAfterLoading;
    10.       }
    11. }
    12. void EquipWeaponAssetAfterLoading(AsyncOperationHandle<Weapon> obj){
    13.     if (obj.Status == AsyncOperationStatus.Succeeded){
    14.        Weapon weapon = obj.Result;
    15.        Debug.Log("...assets successfully loaded Weapon " + weapon);
    16.        EquipWeapon(weapon);
    17.     }
    18. }
    19.  
    I still had to cast it to the proper Class, but it worked the same otherwise.
     
Thread Status:
Not open for further replies.