Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

How to get AssetBundleManifest?

Discussion in 'Scripting' started by ViktorAcadem, Sep 15, 2017.

  1. ViktorAcadem

    ViktorAcadem

    Joined:
    Jun 30, 2016
    Posts:
    11
    Following the instructions on the official site https://docs.unity3d.com/ScriptReference/Caching.html I fail to get AssetBundleManifest neither from the server nor from local storage. The end goal is to get AssetBundle’s hash.

    Main error message in the console is:

    Failed to decompress data for the AssetBundle "Memory"

    I tried to use the following:

    UnityWebRequest - to load from server

    LoadFromFile - to local from local storage

    How to do it correctly?
     
  2. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    2,523
    Can you show the code?
     
  3. ViktorAcadem

    ViktorAcadem

    Joined:
    Jun 30, 2016
    Posts:
    11
    After building I receive the main file and the manifest file.

    In order to check cache and the updated bundle loading I have to indicate hash of the new Bundle which we can obtain only from AssetBundleManifest(for UnityWebRequest). However I cannot make AssetBundleManifest load properly. I tried to indicate path both to the main file (without extension), and to the manifest file (with .manifest extension)

    I try to load AssetBundleManifest using these lines:
    Code (CSharp):
    1.  
    2. AssetBundle manifestBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "dispatcherminigame.manifest"));
    3. AssetBundleManifest manifest = manifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    So in order to get AssetBundle’s hash I have to load the file with .manifest extension, right?
     
  4. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    I am struggling with this too.

    Is it a matter of downloading the manifest individually, or is it indeed available within the loading bundle?

    Bye,

    Jean
     
  5. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    253
  6. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    thanks for your reply.

    the problem is that I can't find the way to do what you say with code.

    I have this:

    AssetBundleManifest _m = (AssetBundleManifest)wwwObject.assetBundle.LoadAsset("AssetBundleManifest", typeof(AssetBundleManifest));

    and that doesn't work, so I would appreciate a snippet on what to do with the wwwObject.assetBundle once it's done being downloaded, so far I haven't found a working snippet from all my searches on google.

    AssetBundleManifest _m = (AssetBundleManifest)wwwObject.assetBundle.mainAsset;

    that doesn't work neither.

    so if you have a working code snippet to share, I would appreciate it very much.

    Bye,

    Jean
     
  7. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    253
    Code (CSharp):
    1. wwwObject.assetBundle.LoadAsset<AssetBundleManifest>("assetbundlemanifest");
    Should work. If not, define what 'doesn't work' means. Do you get an error?

    Also, the bundle containing the manifest is the one named after the folder you built to. It also isn't the file with the .manifest extension, its the bundle file which doesn't have an extension.
     
    Last edited: Aug 23, 2018
  8. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    That doesn't work neither, this line returns null, while the assetbundle main asset is well and can be accessed properly.

    here's the url : https://www.dropbox.com/s/bmunwj8c3ohtfoi/bundletest?dl=1

    Maybe you could point me to a url of a testing asset bundle that works? that would be a good way to rule out that the production of this assetbundle is faulty.

    and I confirm that the .manifest is not the file I load, but indeed the other one, without extension.

    thanks for your patience on this :) I hope we'll get to the bottom of this!

    Jean
     
  9. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    253
    Hi Jean,

    Your bundle returns null on my end too, but I'm using unity 2018.2.2f1 and your manifest is built using 5.6.3f1 by the looks of it (bundles aren't guaranteed to be compatible with different versions).

    What Unity version are you using to build the bundles and project?

    Also, post your downloading code. I suppose unitywebrequest isn't available yet in 5.6.

    Here's an example of a bundle that works for me:

    https://s3-eu-west-1.amazonaws.com/byardev.mysmilez.nl/Android
     
  10. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    yes, it's built with 5.6, but it should work still right?! I'll move to 2017 and 2018 to see if I get a different results.

    I need to get to the lowest working version as I am providing support for PlayMaker, so it woul dbbe good if I can make it work on 5.6

    Bye,

    Jean
     
  11. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    253
    Out of curiosity I downloaded the unity version the bundles were built in, and I can't load the manifest either.

    What build target was the bundle built for? It has to be the same as the platform you try to load it on.

    Post the script used to generate the bundles, and the script that downloads them.
     
  12. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    I am doing this all in editor for standaloneOsX platform target. does that means it will never work in editor?

    Bye,

    Jean
     
  13. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    253
    No, it should load in the editor.

    I just used this build script in the same unity version as you to generate a manifest

    Code (CSharp):
    1. using System.IO;
    2. using UnityEditor;
    3.  
    4. public class CreateAssetBundles
    5. {
    6.     [MenuItem("Assets/Build AssetBundles")]
    7.     static void BuildAllAssetBundles()
    8.     {
    9.         string assetBundleDirectory = "Assets/AssetBundles";
    10.         if(!Directory.Exists(assetBundleDirectory))
    11.         {
    12.             Directory.CreateDirectory(assetBundleDirectory);
    13.         }
    14.        
    15.         BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal);
    16.     }
    17. }
    It outputs this bundle: https://s3-eu-west-1.amazonaws.com/byardev.mysmilez.nl/AssetBundles

    And it loads just fine using the previously shared code. The problem has to be in the bundle file itself, try recreating it.

    This could even be a problem with dropbox hosting. Perhaps they use some funky compression which messes up the file, try regenerating the bundles and hosting it elsewhere or even in streaming assets.
     
  14. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    ok, thanks for confirming on your end that works, I'll debug this Id save it in StreamingAssets already. but as I was loading it from that and was getting null I though it could be something that is only available when you download from the web hence why I tried to put it on the web.

    thanks for your help!

    Bye,

    Jean
     
  15. Nith666

    Nith666

    Joined:
    Aug 1, 2012
    Posts:
    23
    I came across this thread as I had the same problem. I think your mistake is that you're looking in the wrong files. When you create the asset bundles, Unity creates 2 files in your output folder, named after the build target, e.g. WebGL and WebGL.manifest. In order to retrieve the AssetBundleManifest with
    Code (CSharp):
    1. wwwObject.assetBundle.LoadAsset<AssetBundleManifest>("assetbundlemanifest");
    You need to use the file "WebGL" (without the extension). With that AssetBundleManifest you can get all the info needed about the actual AssetBundles
     
  16. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    371
    Hi,

    Thanks for your Input!

    Bye,

    Jean
     
  17. JannickL

    JannickL

    Joined:
    May 18, 2016
    Posts:
    74
    Jesus. This one took me an entire day to figure out what I did wrong. Thanks for creating the thread since it gave me new ideas on how to get this solved.

    However. Here is the code that loads a asset bundle manifest from a given URL:

    You don't have to use the .manifest files!

    This solution also handles multiple asset bundles (like different scenes).

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class AssetBundleCacheSample : MonoBehaviour
    7. {
    8.  
    9.     public string manifestPath = "https://www.your-domain.de/AssetBundlesiOS"; // No file extension (this file gets created when you build your bundles)
    10.     public string assetBundlePath = "https://www.your-domain.de/testbundle"; // Also no extension. This is the actual content asset bundle
    11.  
    12.     private void Start()
    13.     {
    14.         StartCoroutine(DownloadAndCacheAssetBundle());
    15.     }
    16.  
    17.     IEnumerator DownloadAndCacheAssetBundle()
    18.     {
    19.         // Load the manifest (from url)
    20.         UnityWebRequest www = UnityWebRequestAssetBundle.GetAssetBundle(manifestPath);
    21.         yield return www.SendWebRequest();
    22.  
    23.         AssetBundle manifestBundle = DownloadHandlerAssetBundle.GetContent(www);
    24.  
    25.         AssetBundleManifest manifest = manifestBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    26.  
    27.         // Use the default cache here
    28.         Caching.currentCacheForWriting = Caching.defaultCache;
    29.  
    30.         string[] allAssetBundleNames = manifest.GetAllAssetBundles();
    31.  
    32.         foreach(string assetBundleName in allAssetBundleNames)
    33.         {
    34.             // Get hash of bundle
    35.             Hash128 hash = manifest.GetAssetBundleHash(assetBundleName);
    36.             Debug.Log("Hash for bundle " + assetBundleName + " is " + hash);
    37.      
    38.             // Download actual content bundle
    39.             UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, hash, 0);
    40.             yield return request.SendWebRequest();
    41.  
    42.             // This one is crucial for debugging. Code 200 means downloaded from web and Code 0 means loaded from cache.
    43.             Debug.Log(request.responseCode);
    44.  
    45.             // Download the actual content bundle
    46.             AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
    47.      
    48.             // List all the cached versions of the given asset bundle
    49.             List<Hash128> listOfCachedVersions = new List<Hash128>();
    50.             Caching.GetCachedVersions(assetBundleName, listOfCachedVersions);
    51.  
    52.             for (int i = 0; i < listOfCachedVersions.Count; i++)
    53.             {
    54.                 Debug.Log("Found cached version of " + assetBundleName + " version: " + listOfCachedVersions[i]);
    55.             }
    56.  
    57.             // Don't forget to unload the bundle
    58.             bundle.Unload(false);
    59.         }
    60.  
    61.     }
    62.  
    63. }
    64.  
    Hope someone finds this useful.

    Keep it up guys!

    Greets
     
  18. Jumeuan

    Jumeuan

    Joined:
    Mar 14, 2017
    Posts:
    21
    @JannickL : Thank you so much, you save my day! It work like a charm!
     
  19. andrew_pearce_

    andrew_pearce_

    Joined:
    Nov 5, 2018
    Posts:
    77
    @JannickL your solution has one problem: you need to send a request every time you load the bundle. While if you use local manifest file and if you have cached bundle then you can avoid any request to server and speed up loading process.

    BTW I am trying to load bundles from server for almost a week. I learned a lot about Unity and Webrequest in general. Currently Addressables has lots of bugs and limitations which cannot be fixed for more than a half year (including high delays on mobile devices) so they are not recommended to be used.

    UnityWebRequestAssetBundle also has a problem with showing loading progress... it will be 0 for 98% of the time and then quickly move to 45 and then 100%. There was an answer from Unity developers that this is a feature not a bug =) So if you faced the same problem, try to create your own download handler from DownloadHandlerScript.
     
    Last edited: Mar 6, 2020
unityunity