Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Loading AssetBundle's with the same name

Discussion in 'Asset Bundles' started by halilkayim, Oct 23, 2018.

  1. halilkayim

    halilkayim

    Joined:
    Feb 27, 2018
    Posts:
    20
    We have a growing number of AssetBundle's located in the cloud. We download these bundles at runtime and instantiate the prefabs inside them. Our content team seems to have bundled quite a few of these AssetBundle's with the same bundle name even though the files inside them are entirely different. When we try to download and load more than one of these AssetBundle's on the client side, Unity throws an error on the second and later bundles: "Error while getting Asset Bundle: The AssetBundle 'https://myserver.com/files/id/bundlename' can't be loaded because another AssetBundle with the same files is already loaded."

    Our loading code is as follows:
    Code (CSharp):
    1. DownloadOperation = UnityWebRequestAssetBundle.GetAssetBundle( _model.ModelFileUrl, Convert.ToUInt32(_model.UpdatedAt), 0).SendWebRequest();
    2.  
    3. DownloadOperation.completed += operation =>
    4. {
    5.     var webRequest = DownloadOperation.webRequest;
    6.     if (webRequest.isNetworkError || webRequest.isHttpError)
    7.     {
    8.         throw new Exception($"Error while downloading asset: {webRequest.error}");
    9.     }
    10.  
    11.     _assetBundle = DownloadHandlerAssetBundle.GetContent(webRequest); // this is the line that causes the error
    12.     if (!_assetBundle)
    13.     {
    14.         throw new Exception($"Could not get content from AssetBundle with ID: {_model.Id}");
    15.     }
    16.     // use _assetBundle to instantiate prefab
    17. }
    Right now, we can handle this error so no crashes happen, but we would like to know if there is a way to solve this without re-bundling the AssetBundle's with the same bundle name. Any insight on this would be much appreciated.
     
  2. DORNE

    DORNE

    Joined:
    Jul 4, 2017
    Posts:
    4
    I have the same problem and I don' know how to handle this error and avoid crashes. Could you tel me how you did it ?
    Thanks
     
  3. halilkayim

    halilkayim

    Joined:
    Feb 27, 2018
    Posts:
    20
    Unity's API doesn't seem to support this in any way, so we had to write a custom class AssetBundleManager which handles loading and caching AssetBundle's, so that we wouldn't attempt to load two bundles with the same name. As for the pre-existing bundles, unfortunately we had to re-bundle them all.
     
  4. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    162
    You need to switch to using this version of the GetAssetBundle API:

    Code (CSharp):
    1. public static Networking.UnityWebRequest GetAssetBundle(string uri, CachedAssetBundle cachedAssetBundle, uint crc);
    Reason:
    Asset bundle names can contain path notations
    My/AssetBundle1/prefabs
    and
    My/AssetBundle2/prefabs
    which is not something that can be determined from a URL automatically easily:
    https://mygames.com/mygame/bundles/My/AssetBundle1/prefabs
    vs
    https://mygames.com/mygame/bundles/My/AssetBundle2/prefabs
    . In both of those cases the cached asset bundle name becomes
    prefabs
    which is incorrect. The
    CachedAssetBundle
    struct resolves this issue by requiring you to provide the cached asset bundle name and hash instead of us pulling it from the URL. So you construct a
    CachedAssetBundle
    with the name
    My/AssetBundle1/prefabs
    and correct hash, and the cache will then store it using that name and hash and be able to distinguish it correctly from
    My/AssetBundle2/prefabs
    .