Search Unity

Asset bundle manifest. Download or load from device?

Discussion in 'Scripting' started by Dextozz, Sep 20, 2019.

  1. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    All right, I've been trying to wrap my head around asset bundles for days now. Online documentation is very weak and the internet is full of outdated, depracted or obsolete methods of loading asset bundles. I've managed to figure out how caching works (mostly), by following this documentation guide:
    https://docs.unity3d.com/ScriptReference/Caching.html

    Now, my question lies at the part where we are loading the asset bundle manifest. Why would we load it locally? Isn't the whole point of the manifest to notify the app which asset bundles need to be redownloaded? If it is, then how would the app know which asset bundles need to be updated if the manifest is stored locally? Can someone suggest an idea of how to approach this issue? Maybe I'm thinking about asset bundles completely wrong.

    P.S. - Is it a good idea to store the asset bundle manifest file locally, then try to download it every time the app starts. If the download fails then read the local version? It seems logical, but I have no clue how to incorporate that into the code as I've seen some people use StreamingAssets with no explanation why.

    Also, if you can paste in any code on how you work with asset bundles it would also be very appreciated.

    Thanks.
     
  2. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
  3. Makkus

    Makkus

    Joined:
    Sep 14, 2015
    Posts:
    20
    I'm lost with the exaclty same problem. I can't find any working example of loading the asset bundle manifest from a remote bundle (actually any other bundle than the root-folder thing, named after the build target). So how to resolve dependencies of remote asset bundles. They can't possibly be known to the local main manifest, as the benefit of reomote bundles is that they are created independetly (or even after) the application deployment. I would be nice to see a brief and simple example of how to correctly load a remote bundle with dependecies.
     
  4. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    I've figured out how to do it. There are 2 paths you can take.
    1) Don't use the manifest. Instead, use a .json file that holds your versions.
    2) Use the asset bundle manifest

    I still have no idea why anyone would store the bloody thing locally when it's completely pointless to do so. The idea is that you download you manifest (or .json) every time your app starts with an online connection. It shouldn't be a problem since the .json file is like 1KB. Then, check if anything needs to be updated, and if it does, update it.

    What you want to do is get a server from where you'll be downloading the bundles from. I've used AWS but you can use google drive or dropbox to start (there's a trick to make those links be direct download links). Once you have that setup, use the Unity Web Request to download your manifest (or .json) first. After that, download others as needed. If you are using the google drive/dropbox approach, you'll need to hardcode links in your code so that your app knows where to download them from. AWS lets you create permanent links so you can switch out files without changing the link.

    If you have a specific issue, let me know. I don't have the access to the project anymore, but I might be able to remember how it's done. Also, if you can, switch to addressables.
     
    akhror_unity likes this.
  5. Makkus

    Makkus

    Joined:
    Sep 14, 2015
    Posts:
    20
    Thanks, a lot to your tips. I start to realize that Unity is not designed to be extendable - unfortunately. I have started using addressables but they make things even worse for me. To my knowledge there isn't even a way to load addressables from a custom URL, all locations (remote or local) must be defined during player building! This is stone-age... So I refactored back to plain asset bundles.

    Do I understand you right that you suggest to either derive a custom manifest (JSON) from the one unity builds (1) or to replace the local (single) 'master' manifest with a version downloaded (2)? Doing so I would need write permission to the streaming assets folder, which I might or might not have (depending on the way the application will be installed later).

    In my case I would like to implement a simple "premium" content feature. So users can add content which is not part of the regular build. On every start my application is already retrieving a configuration file from the server. So, I felt it would be rather trivial to include some asset bundle urls in there, and go on loading them. Now I must learn that although I can include the urls and the bundle, there will be no dependency resolving for the remote bundles. It’s really hard to believe that I am supposed to implement this on my own…
     
  6. Makkus

    Makkus

    Joined:
    Sep 14, 2015
    Posts:
    20
    A, now I think I got you: I can store a copy of the magic "asset bundle mainfest bundle" on the server, load it at app start and use this one for dependecy resolution, not the (outdated) one that is stored locally.
     
    Dextozz likes this.
  7. Dextozz

    Dextozz

    Joined:
    Apr 8, 2018
    Posts:
    493
    Yes.

    Also, there's no need for you to derive json at all. Just write a small one manually and deserialize it when needed.
     
  8. nilsdr

    nilsdr

    Joined:
    Oct 24, 2017
    Posts:
    374
    If you use bundles for patching content it makes little sense to store the manifest locally, except for when the user on first app start is offline and you want to provide a fallback. Store the downloaded manifest locally and use it as a 'last known content state'

    Assetbundles have a second usecase, runtime asset/memory management. For this usecase, depending on your requirements, it can make sense to include bundles and manifest in streaming assets.

    Assetbundles are a 'low level' functionality. If you're looking for an off the shelf content management solution look into addressables, which is an abstraction made by unity that will make your life easier
     
  9. Makkus

    Makkus

    Joined:
    Sep 14, 2015
    Posts:
    20
    I tried the manifest solution download, which works - but for some reason it feels kind of wrong to me (conceptually). I rather wanted to have 'idependet' remote bundles carrying their own dependencies. I realized that the manifest is actually associated with a build process (not with a bundle). Thus I created a separate build process for my remote test bundle. This way I can query the generated remote bundle for it's manifest and the dependencies - no need to look at the local one. Unfortunately, this manifest will only contain depdency information when all dependent bundles as included in the build. Which enforces me to re-build all (remote and local) bundles when updating the remote one. Then I delete the superfluos local bundles again. This way I get a remote bundle with all dependency data in it. This process will be really much faster if I would be able to read the dependencies from the AssetDatabase and put them into the manifest somehow (as AssetDatabase knows the dependecies without building erverything). But there seems to be no way to manipulate depency properties on the manifest.

    Addressables
    I have tested addressables some time ago as they seem to be the better solution, But I couln't find any information about who to load addressables for a URL not defined during build. I learned that I can change the content of a given remote location, but there seems to be no way to send a URL and a list of addressable names to the game and make it load addressables from this URL. I would be very interested in any info on how this could be done with addressables.