Search Unity

Asset Bundles for on demand character loading?

Discussion in 'Asset Bundles' started by ItsLeeOwen, Jun 18, 2017.

  1. ItsLeeOwen

    ItsLeeOwen

    Joined:
    Jun 3, 2017
    Posts:
    11
    I'm looking for best practice recommendations from others when considering when to use asset bundles. I don't need assets to be remotely downloadable, or dlc bundles, I'm looking more at the balance between memory & io reads. Basically when is it better to load 4GB of content into memory at the start of a game, or load in assets on demand during gameplay, and the things to consider.

    Is it acceptable to load bundles & assets during runtime gameplay? Will your FPS suffer? For example would you use asset bundles to dynamically load unique monster prefabs on demand during runtime if you have a total collection of 200 types of monsters, and will load them in batches of 2-5 overtime through interactive gameplay progression without load screens?

    Would it be a acceptable to use a single AssetBundle per monster which contain it's graphics, audio, etc, and load that bundle during gameplay when the monster is needed? Or is it better to use a larger bundle which contains many monster assets?

    Will your FPS always drop when loading from assetbundles during gameplay, and would it be advisable to load a large batch of assets in a single bundle during a load screen, such as between waves of enemies? If loading bundles + assets in large batches is preferable, what guidelines are there for memory footprint, how do you determine what size is acceptable for a bundle?

    Any tips, techniques, or general concepts are appreciated. I've looked at the profiler, and I see about 150ms spikes during runtime when a bundle + asset load where FPS drops to roughly 15ms, which is leading me to think that perhaps AssetBundles should only be used outside of actual gameplay, such as loading screens, or clearly defined pauses between gameplay.
     
    Last edited: Jun 18, 2017
  2. ItsLeeOwen

    ItsLeeOwen

    Joined:
    Jun 3, 2017
    Posts:
    11
    I've attached the spikes in the profiler during runtime when using AssetBundle. They're very brief, and I haven't tried running on a device yet, so I don't actually know how perceptible these are in gameplay.

    Screen Shot 2017-06-18 at 10.24.23 AM.png Screen Shot 2017-06-18 at 10.24.08 AM.png
     
  3. ItsLeeOwen

    ItsLeeOwen

    Joined:
    Jun 3, 2017
    Posts:
    11
    I tried both sync & async AssetBundle loads, and both produce roughly the same FPS spike & cpu usage.
     
  4. Reichert

    Reichert

    Unity Technologies

    Joined:
    Jun 20, 2014
    Posts:
    63
    There is a small but unavoidable cost to loading asset bundles, so a lot depends on the goals for your game. if occasional hitches are unacceptable, then you will need to pre-load any asset bundles you wish to load assets from at an acceptable time and place. Later loading assets from the bundles will also have some performance implications depending on what's in the bundle. There are some recent improvements in that area - in 2017.1 and later, textures are streamed and uploaded directly to the GPU. However there is still a cost to loading any associated shader that isn't already loaded (this is a known issue that is being investigated). So really you are going to also want to pre-load any assets from the bundle that will be used during the section of gameplay where consistent framerate is critical.

    Again the answer to this really depends a lot on your goals. One large bundle with many assets would probably suit a design where a consistent framerate is required. That way you have a single asset bundle load, followed by pre-loading any assets required.

    Each asset bundle loaded incurs an incremental cost in memory overhead. Some of this cost is platform dependent and not in your control, but there are a couple of things you can do to minimize the memory overhead of bundles:
    • Use LZ4 (chunk based) compression with your bundles. There are two ways to do this: 1) build them initially with the BuildAssetBundleOptions.ChunkBasedCompression option. or 2) use the caching mechanism built-in to UnityWebRequest, which will automatically re-compress your bundles to use chunk based compression when they are stored in the cache.
    • Do NOT mark large folders to be included in an asset bundle. Instead, only mark the specific assets that you intend to load by name at runtime. Marking a folder to be included in an asset bundle will add the full pathname of every asset in that folder to a name lookup map that is loaded when the asset bundle is loaded at runtime. Additionally, 2 extra maps are generated from the full path name - one for "file name without extension" and one for file name with extension". So this actually contributes to both load time and memory usage. In 2017.1, we added two new build options to disable each of these name path lookup tables independently - see BuildAssetBundleOptions.DisableLoadAssetByFileName and BuildAssetBundleOptions.DisableLoadAssetByFileNameWithExtension
     
    ItsLeeOwen likes this.