Search Unity

How to correctly setup Scene Addressables

Discussion in 'Addressables' started by Uli_Dantas, Aug 7, 2018.

  1. Uli_Dantas

    Uli_Dantas

    Joined:
    Aug 21, 2014
    Posts:
    5
    Hi,
    I'm trying to setup an existing project that wasn't using asset bundles before, to use addressables.
    My setup is Unity 2018.2.1 and Addressable 0.2.1, my game consists of a Start scene, where the player simply chooses an button to load a minigame. The minigame will be a independent scene loaded in additive mode. When the minigame ends, the scene unloads and the player return to the main hub.

    What I'm trying to do is make each minigame scene addressable, so all it's content can be loaded and unloaded only when necessary.
    The problem is: I tried to add each scene to a content group, and set them to Pack Separately. In code I was able to load the scenes, but every single script component (my own components, for example, an MinigameBooController, MinigameBooPlayer) is missing after the scene loads.
    I'm using
    Code (CSharp):
    1. var asyncLoad = UnityEngine.AddressableAssets.Addressables.LoadScene(name, LoadSceneMode.Additive);
    and also tried to preload the dependencies before loading the scene like this:
    Code (CSharp):
    1. var preload = UnityEngine.AddressableAssets.Addressables.PreloadDependencies(name, null);
    I also tried to add the [UnityEngine.Scripting.Preserve] tag to each one of my classes, but it didn't work.

    So, how should I setup this? Do I need to add every single used prefab, model, texture, script along with the scene as addressable? Or the scene as addressable should automatically link the necessary dependencies.

    Also, using the scenes as adressables, should I remove them from the build settings? (It worked both ways, but no idea which is the correct way)

    I tested building to Standalone Windows, and WebGL build targets. Both didn`t work.

    Thanks
     
  2. PaulBurslem

    PaulBurslem

    Unity Technologies

    Joined:
    Oct 7, 2016
    Posts:
    79
    Hi, thanks for your feedback. I have reproduced this issue locally and we should have a fix soon. The problem is that when you make the group pack separately, the generated bundles use the name of the group and the address. When assets in sub directories resolve to the same address, this results in bundle name collisions. For now, you can work around this by ensuring that each scene has a unique address as the solution will probably involve detecting address collisions and giving more detailed error messages.
     
  3. Uli_Okm

    Uli_Okm

    Joined:
    Jul 10, 2012
    Posts:
    95
    Thanks @PaulBurslem, but the work around also didn't work.
    I tried pack then together too, but after the scene loads, my scripts are still missing.
    This is my setup:
    upload_2018-8-9_20-36-11.png

    I will just wait for the real fix for a while then :D
     
  4. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    wow so you can make an entire scene addressable, and that includes everything in it? is this fixed?
     
  5. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    I also have the same exact issue, any ideas or work around yet?
     
  6. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    The original post is from a very old version of addressables. For those facing this issue now, can you please update with some context as to what exactly you're running into?
     
  7. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    the issue that I was running into is that the shaders started to look pink when I move to packed play mode using the editor, but doing some research I figured that pink shaders will only appear on the editor since the bundle was built for Android. what I'm stacked on right now is how to retrieve the progress percentage for the IAsyncOperation for loading a scene as an AssetReference.
     
  8. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    @almertineshop did you tried the PercentComplete property of the IAsyncOperation ?
     
  9. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    That's what i use but all I have is 0 at the beginning of the loading and the scene loads after a while, so no progress showing, here is my code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5. using UnityEngine.AddressableAssets;
    6. using UnityEngine.SceneManagement;
    7. using UnityEngine.ResourceManagement;
    8. using UnityEngine.ResourceManagement.AsyncOperations;
    9.  
    10. public class MyAdressablesManager : MonoBehaviour
    11. {
    12.  
    13.     public AssetReference AddressableScene;
    14.  
    15.  
    16.     public void functionToStartLoading()
    17.     {
    18.      
    19.  
    20.         var async = Addressables.LoadScene(AddressableScene);
    21.  
    22.         async.Completed += LoadComplete => {
    23.             Debug.Log("LOADED! ");
    24.          
    25.         };
    26.  
    27.  
    28.         StartCoroutine(LoadProgress(async));
    29.     }
    30.  
    31.     private IEnumerator LoadProgress(IAsyncOperation<Scene> async)
    32.     {
    33.      
    34.  
    35.         while (!async.IsDone)
    36.         {
    37.  
    38.             Debug.Log(async.PercentComplete);
    39.  
    40.  
    41.             yield return null;
    42.  
    43.         }
    44.  
    45.  
    46.     }
    47.  
    48.     private void LoadComplete(IAsyncOperation<Scene> inOperation)
    49.     {
    50.         if (inOperation.Status == AsyncOperationStatus.Succeeded)
    51.  
    52.         {
    53.             Debug.Log("Downloaded " + inOperation.Result.name);
    54.  
    55.         }
    56.          
    57.          
    58.  
    59.         else
    60.             Debug.Log("Error: " + inOperation.OperationException.Message);
    61.     }
    62.  
    63.  
    64.  
    65. }


     
    Last edited: Mar 25, 2019
  10. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Hmmmm, I would write it like this, can you try ?


    Code (CSharp):
    1. public class MyAdressablesManager : MonoBehaviour
    2. {
    3.     public AssetReference AddressableScene;
    4.  
    5.     public void functionToStartLoading()
    6.     {
    7.         StartCoroutine(LoadRoutine());
    8.     }
    9.  
    10.     private IEnumerator LoadRoutine()
    11.     {
    12.         var async = Addressables.LoadScene(AddressableScene);
    13.  
    14.         while (!async.IsDone)
    15.         {
    16.             Debug.Log(async.PercentComplete);
    17.             yield return null;
    18.         }
    19.      
    20.         // At this point the scene is loaded and referenced in async.Result
    21.         Debug.Log("LOADED!");
    22.  
    23.         Scene myScene = async.Result;
    24.     }
    25. }
     
  11. wangyucheng1992

    wangyucheng1992

    Joined:
    Feb 19, 2019
    Posts:
    59
    hi ,who can tell me how to use this function,I do not know the parameter what is in the yellow rect,who can show an example for me,thank you!
     

    Attached Files:

  12. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    Hi, Thanks for the refined code but it gives the same results, always no progress just 0 and then the scene loads.

    I hope @unity_bill has some thoughts.

     
  13. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Honestly, I've never tried the PercentComplete property.

    Maybe your scene is instant loaded so the percentage is never printed at value 1?
    Seems like you enter the while loop only one time.
    You know the first time that IsDone is false you enter the while that print the percentage to the console then the next time IsDone should be at true. Did you get the message "LOADED" that is on my code snippet? If yes, try to print the percentage here, it should be at one or a hundred depending on if the value is normalized or not.
     
  14. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    Hi, Thanks for your reply I get the message "LOADED" as in your code, I will try to check the points that you mentioned and verify with a bigger scene maybe, and I'll try to find a workaround the while loop, I have no idea how I'll do it but I'll do some research and look for other options.
     
  15. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    I solved the progress issue, I had another script that deactivates the percentcomplete function without i noticed it, thanks for the support.
     
    Last edited: Apr 1, 2019
  16. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    You're welcome :)
     
  17. almertineshop

    almertineshop

    Joined:
    Dec 29, 2017
    Posts:
    14
    Now, I'm stuck again, what I want to do is to check if the scene is cached if it was downloaded before, so the player won't download the scene every time he wants to play. So what i'm trying to do is to activate a play button if the scene is already in cache, and a download button if it is not available.

    I tried using Caching.IsVersionCached to check if 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.     }
     
  18. NoBudget_Studios

    NoBudget_Studios

    Joined:
    Dec 20, 2017
    Posts:
    1
    Hi there! Any solution?
    It won't load my scene too.


    Code (CSharp):
    1.     public static IEnumerator InitCreate<T>(string assetLabel, List<T> assets) where T : Object
    2.     {
    3.  
    4.         AsyncOperationHandle addresableContainer_async = Addressables.LoadAssetsAsync<T>(assetLabel, op =>
    5.             {
    6.                 if (!assetLabel.Contains("scene"))
    7.                 {
    8.                     Debug.Log("Congrats it's a gameObject!");
    9.                     ///assets.Add(GameObject.Instantiate(op));
    10.                     GameObject.Instantiate(op);
    11.                     Debug.Log("DONE! GO");
    12.                 }
    13.                 else
    14.                 {
    15.                     Debug.Log("Congrats it's a scene!");
    16.                     //Addressables.LoadSceneAsync(op, LoadSceneMode.Additive);
    17.                     //Addressables.LoadScene(op, LoadSceneMode.Additive,true,2);
    18.                     assets.Add(op);
    19.                     Debug.Log("DONE! SCENE");
    20.                 }
    21.                
    22.             });
    23.  
    24.  
    25.         #region loadingBar
    26.         while (!addresableContainer_async.IsDone){
    27.                 loadingBar_image.fillAmount = (addresableContainer_async.PercentComplete / 0.9f);
    28.                 Debug.Log(addresableContainer_async.PercentComplete);
    29.                 yield return null;
    30.             }
    31.         loadingCanvas_go.SetActive(false);
    32.         #endregion
    33.        
    34.         yield return addresableContainer_async;
    35.     }
     
    JoRangers likes this.
  19. xLeo

    xLeo

    Joined:
    Sep 21, 2010
    Posts:
    194
    A few things to remember when using Addressables:
    • An AssetReference may have some dependencies that need to be (down)loaded first, so for preemptive download operations use "Addressables.DownloadDependenciesAsync". That method will download all dependency tree for a given asset reference;
    • Use "Addressables.GetDownloadSizeAsync" to check if an AssetReference is cached or not (it will return 0 if it is up-to-date);
    • IMPORTANT: at least in our latest tests (from 1-2 months ago), in order to properly handle download exceptions we needed to call "Addressables.DownloadDependenciesAsync" and then "Addressables.LoadSceneAsync".
      • Addressables.LoadSceneAsync by itself will download and load the scene, but if an exception is raised on the download process (let's say an endpoint is not accessible) it won't be properly handled. I have already reported this to Unity but it seems not fixed yet.
    These are my considerations about using Addressables to load scene, the documentation could use some extra love. :)
     
    DeathPro, xucian, rkvieira and 10 others like this.
  20. javierfed

    javierfed

    Joined:
    Apr 10, 2015
    Posts:
    50
    what issues could arise that would prevent a scene in a bundle from loading, producing a "Scene couldn't be loaded because it has not been added to the build settings or the AssetBundle has not been loaded." I am referencing it via an AssetReference object and trying to load it async, but I keep getting this error even though I am certain I have the scene in question in the bundle and labeled correctly.

    Addressables even builds out a seperate "*_scenes_all.bundle" that I assume has the scenes... but the error persists.