Search Unity

How to download an assetBundle from server and use it in app?

Discussion in 'Asset Bundles' started by zyonneo, Dec 4, 2019.

  1. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    I have created assetBundles-5 prefab models were given the name 'kitchen' and around 3 prefab models the name 'furniture' for the created assetbundles.The code I used for making AssetBundles is as follows and kept in the Assets/Editor folder.

    Code (CSharp):
    1.  
    2. public class Assetcreate : Editor
    3. {
    4.     [MenuItem("Assets/Build Home Assets")]
    5.     static void BuildKitchenAssets()
    6.     {
    7.         BuildPipeline.BuildAssetBundles("/Users/ar/Desktop/HomeBundles",BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.StandaloneOSX);
    8.     }
    9. }
    In the desktop I have the created AssetBundles.I upload these files in the server using Filezilla(with Transfer>TransferType>Binary).
    The code for downloading the assets are as follows,

    Code (CSharp):
    1.  
    2. public int version=0;
    3. public string url=http://safebuild.net/hari/bundle/;
    4. public string AssetName="Chair-Almera";
    5.  
    6. void Start()
    7. {
    8.         StartCoroutine(GetBundles());
    9. }
    10.  
    11. IEnumerator GetBundles()
    12. {
    13.  
    14. while (!Caching.ready)
    15.             yield return null;
    16.  
    17.         //Load the assetBundle file from Cache if it exists with the same version or download and store it in the cache.
    18.         using (WWW www = WWW.LoadFromCacheOrDownload(url, version))
    19.         {
    20.             yield return www;
    21.             if(www.error!=null)
    22.             {
    23.                 throw new Exception("WWW download error: "+www.error);
    24.             }
    25.             AssetBundle bundle = www.assetBundle;
    26.             if(AssetName==" ")
    27.             {
    28.                 Instantiate(bundle.mainAsset);
    29.             }
    30.             else
    31.             {
    32.                 //GameObject go=bundle.LoadAsset<GameObject>(AssetName);
    33.                 GameObject go = bundle.LoadAsset(AssetName) as GameObject;
    34.                 Instantiate(go);
    35.             }
    36.  
    37.             bundle.Unload(false);
    38.         }
    39.  
    40.     }
    41.  
    Now few errors occured when I click play in the editor and no prefabs came on the Game view.

    1)Error while downloading Asset Bundle: Failed to decompress data for the AssetBundle 'http://safebuild.net/hari/bundle/'.

    2)/Users/ar/Documents/Unity Projects/Kitchen/Assets/Scripts/ABLoadOnline.cs(26,26): Warning CS0618: 'WWW' is obsolete: 'Use UnityWebRequest, a fully featured replacement which is more efficient and has additional features' (CS0618) (Assembly-CSharp)

    3)/Users/ar/Documents/Unity Projects/Kitchen/Assets/Scripts/ABLoadOnline.cs(29,29): Warning CS0618: 'AssetBundle.mainAsset' is obsolete: 'mainAsset has been made obsolete. Please use the new AssetBundle build system introduced in 5.0 and check BuildAssetBundles documentation for details.' (CS0618) (Assembly-CSharp)


    How to download the AsssetBundles files and download for IOS/Android persistant path.I want an efficient way to do this.Should I download all the assetbundle files from the server (folder structure) to the device path?If already downloaded, dont download the bundle again.At the same time if I have added new models to the 'kitchen' assetbundle it has to check and update the bundle.
     
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    The link points to a web page listing your bundles. You should be downloading the bundles themselves. Also, use UnityWebRequest istead of old WWW.

    Both WWW and UnityWebRequest give you ability to use built-in caching system.
     
    phobos2077 and zyonneo like this.
  3. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    For kitchen assetbundle I have to give
    Code (CSharp):
    1.  
    2. public string url="http://safebuild.net/hari/bundle/kitchen";
    3.  
    So if I have multiple assetbundles I have to give multiple links ? Also
    I tried the following code but this is not cached.
    Code (CSharp):
    1. using(UnityWebRequest uwr=UnityWebRequestAssetBundle.GetAssetBundle(url,0))
    2. {
    3. yield return uwr.SendWebRequest();
    4. if (uwr.error != null)
    5. {
    6. throw new Exception("WWW download error: "+uwr.error);
    7. }
    8. AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
    9. if(AssetName==" ")
    10. {
    11. Instantiate(bundle.mainAsset);
    12. }
    13. else
    14. {
    15. GameObject go = bundle.LoadAsset(AssetName) as GameObject;
    16. Instantiate(go);
    17. }
    18. }  
    I came across the following code
    Code (CSharp):
    1. public static Networking.UnityWebRequest GetAssetBundle(string uri, CachedAssetBundle cachedAssetBundle, uint crc);
    What is CachedAssetBundles cachedAssetBundle ?Should I give a persistent data path there? Every time I update AssetBundle I need to increment crc?
    Code (CSharp):
    1. using(UnityWebRequest uwr=UnityWebRequestAssetBundle.GetAssetBundle(url,XXXXXXX,0))
     
  4. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    Read documentation on UnityWebRequest.GetAssetBundle. It doesn't cache if only URL is provided, but if you provide hash or CRC, it does save bundle on disk and reloads it the next time.
    If you have multiple bundles that you will update and don't want to update your app when you do, you should be hosting information about the bundles as well, have a look at asset bundle manifest.
     
    Dan_G likes this.
  5. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    I copied the crc number from manifest file and gave it as uint and tried the code below.
    Code (CSharp):
    1.    
    2.     public uint crc= 3720593779;//copied from http://safebuild.net/hari/bundle/kitchen.manifest
    3.     public string url;
    4.     public string AssetName;
    5. using(UnityWebRequest uwr=UnityWebRequestAssetBundle.GetAssetBundle(url,crc))
    6.         {
    7.             yield return uwr.SendWebRequest();
    8.  
    9.  
    10.             if (uwr.error != null)
    11.             {
    12.                 throw new Exception("WWW download error: "+uwr.error);
    13.             }
    14.             AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
    15.             if(AssetName==" ")
    16.             {
    17.                 Instantiate(bundle.mainAsset);
    18.             }
    19.             else
    20.             {
    21.                 //GameObject go=bundle.LoadAsset<GameObject>(AssetName);
    22.                 GameObject go = bundle.LoadAsset(AssetName) as GameObject;
    23.                 Instantiate(go);
    24.             }
    25.          
    26.         }
    This is still downloading but not caching.Any tutorials?
    Are these the steps given below?
    Step 1-Download the manifest file into Application.Persitentpath.
    Step 2-Load the manifest
    Step 3-Get the crc or hash
    Step 4-Download assets using uri and newly obtained crc/hash
     
    Last edited: Dec 5, 2019
  6. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    How do you check if bundle is cached or not?
     
  7. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    using (WWW www = WWW.LoadFromCacheOrDownload(url, version))
    Using WWW it required only this much but for UnityWebRequest it is a bit confusing.Need to add versions?
     
  8. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
  9. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    https://docs.unity3d.com/ScriptReference/Networking.DownloadHandlerAssetBundle-ctor.html
    I read and tried this script.Similiar one.
    For version I have given zero in the inspector.So if I update the assetbundles then I need to increment version?

    Code (CSharp):
    1.  
    2. IEnumerator DownloadBundles()
    3.     {
    4.         using (var uwr = new UnityWebRequest(url, UnityWebRequest.kHttpVerbGET))
    5.         {
    6.             uwr.downloadHandler = new DownloadHandlerAssetBundle(url,version,0);
    7.             yield return uwr.SendWebRequest();
    8.             AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(uwr);
    9.             if (AssetName == " ")
    10.             {
    11.                 Instantiate(bundle.mainAsset);
    12.             }
    13.             else
    14.             {
    15.                 //GameObject go=bundle.LoadAsset<GameObject>(AssetName);
    16.                 GameObject go = bundle.LoadAsset(AssetName) as GameObject;
    17.                 Instantiate(go);
    18.             }
    19.  
    20.             bundle.Unload(false);
    21.         }
    22.     }
    23.  
    24.  
     
  10. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,732
    With version being zero it is not caching, as documented. Yes, if you update the bundle, you have to increment the version, otherwise you'll be loading the same bundle from cache.
     
  11. zyonneo

    zyonneo

    Joined:
    Apr 13, 2018
    Posts:
    386
    I have given '0' for version in the inspector,I checked the cache folder on mac and I found a Unity folder which contains the cached data for assetbundle.That means it is caching.Once I alter the asset names I am getting different prefabs which I stored as assetbundle on the server instantly.Earlier for each asset names given I had to wait for every single one of them to download.
     
  12. See_Sharp

    See_Sharp

    Joined:
    Mar 3, 2016
    Posts:
    74
    Unity caches by given URL. If you reupload assets with different names and cache them with version 0, it will download the 'new' assetbundle.

    If you want to update an assetbundle on the server (and obviously, don't want to change the name) your client has to know if it changed. This is done by prodiving the manifest and downloading that first, then you can check the hash and supply it to the unity web request, so it knows if the hash changed it needs to redownload the assetbundle.