Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Choosing the right asset bundle compression

Discussion in 'Scripting' started by liortal, Mar 3, 2016.

  1. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    We started using asset bundles in our project (using Unity 5.3.2p3).
    I've read the Unity manual part about asset bundle compression (here: http://docs.unity3d.com/Manual/AssetBundleCompression.html)

    In that link, it is metnioned that LZ4 (which is available starting with Unity 5.3):
    Also, the docs mention how to handle bundles that are added to StreamingAssets:
    We have asset bundles where each bundle contains a single prefab (and its dependencies).

    1. Why should bundles that are built into StreamingAssets use ChunkBasedCompression ? this results in a larger deployed package size for the game.

    2. For bundles with only a single prefab that is loaded, does LZ4 have any significant advantage over LZMA ?

    3. We use LoadFromFile. In that link (in the table) it says that when using LZMA, performance is "reading from disk and then recompressing into LZ4". Is that so? I thought it only happens during download.

    Any tips for optimizing the way we handle asset bundles will be helpful! (currently we use the default - LZMA)
     
  2. ratmat2002

    ratmat2002

    Joined:
    Jun 13, 2014
    Posts:
    35
    Hi liortal,

    LZ4 decompression is way faster than LZMA decompression. The tradeoff is that LZ4 bundles are larger than LZMA bundles.

    We keep all of "system" assets that we want immediately available to our app inside AssetBundles in the StreamingAssets folder. This includes things like dialogs, the initial game tutorial, etc. These are things we want the user to see immediately without having to wait to download them from our server. We found that LZMA decompression caused a pretty serious slowdown in the startup time of our app. With LZMA, we would see 10-15 second startup times as the bundles in the StreamingAssets folder were decompressed. Using LZ4, the loading is nearly instantaneous (1-2 seconds).

    You may ask: "Why we you just keep these assets in the Resources folder and not inside an AssetBundle?"

    The reason is that many of these "system" assets are referenced by other assets contained in AssetBundles that are downloaded from our servers. Assets placed in the Resources folder aren't available to assets inside AssetBundles! Instead a copy of the asset found in the Resources folder will be added to each downloadable AssetBundle that references it. If you have commonly used assets like fonts, shaders, etc. every downloadable AssetBundle would include its own copy causing every downloadable bundle to be larger than it needs to be.

    By keep these "system" assets inside an AssetBundle in the StreamingAssets folder compressed with LZ4, we get very fast load times and don't have duplicates in every downloadable asset bundle.

    Keep in mind that while LZ4 AssetBundles are larger than LZMA AssetBundles, the AssetBundles in the Streamingssets folder will still be compressed further when included in a .ipa (iOS) or .jar (Android) file so the binary you place in the App Stores won't be much larger.
     
  3. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    @ratmat2002 thanks for the detailed answer ;)
    Your particular scenario involves a bunch of bundles that should be made ready immediately. Could you elaborate on their exact size (or total size) ?

    We include asset bundles in the streaming assets, but these get loaded on demand. Would you say we would still benefit from faster load times if we compress using LZ4 ? also, what is the size difference from your experience ?
     
  4. ratmat2002

    ratmat2002

    Joined:
    Jun 13, 2014
    Posts:
    35
    Currently, we are deploying three AssetBundles to the StreamingAssets folder. They are all loaded immediately at startup and required for the app to continue. The total combined size of the three LZ4 compressed AssetBundles is (16.5Mb): one of them is 14.5Mb and the other two are about 1Mb each.

    LZMA compresses on average 34% smaller than LZ4 for AssetBundles we have built to deploy on our servers. This average is based on the results of about 50 AssetBundles that range in size from 3Mb - 20Mb.

    There are other benefits to using LZ4 compression in addition to the fast loading times. Assets in LZ4 compressed AssetBundles can be loaded directly from the compressed LZ4 file without needing to decompress the entire AssetBundle. If you use LZMA, the entire AssetBundle must first be decompressed into a separate buffer to read even a single Asset. So, the hardware resources required for LZ4 AssetBundles are just the disk space of the compressed LZ4 bundle plus a small memory buffer to decompress chunks of the bundle. The hardware requirements for LZMA AssetBundles are the disk space of the compressed LZMA bundle plus a memory buffer equal to the entire uncompressed size of all of the assets in the LZMA bundle.

    This is important for us because the total size of our app using LZMA AssetBundles on iOS devices (once all AssetBundles had been downloaded from our servers) was close to 1.5Gb. This was essentially the size of all of the uncompressed assets after being downloaded and uncompressed in the WWW cache. Using LZ4, out app size is much smaller (about 700k) because disk space is needed to store all of the uncompressed bundles in the cache. LZ4 bundles can remain compressed once in the WWW cache.
     
    chrismarch and alimustafa90 like this.
  5. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    Does anyone know why the documentation page for this was removed? where can i read more about asset bundle compression ?
     
  6. kiwipxl

    kiwipxl

    Joined:
    Jun 9, 2015
    Posts:
    11
  7. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,559
    That's docs for Unity 5.3, i wouldn't call that 'new' ;)
     
    lol_Unity_3Dim likes this.
  8. Lesha-VH

    Lesha-VH

    Joined:
    Jul 3, 2012
    Posts:
    92
    Could someone answer the question please?

    I have one big UNCOMPRESSED asset bundle.
    I would like to load one texture.
    On iOS/Andoird will be the WHOLE asset bundle loaded into memory - or just required binary part will be loaded and texture created and return

    Thanks!
     
  9. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,064
    It depends on how you load it.
    https://docs.unity3d.com/530/Documentation/Manual/AssetBundleCompression.html
    Yes the documentation is old but most of it should be still valid.
    WWW
    is pretty much deprecated. So if you're using that, convert it to
    UnityWebRequest
    instead. In Unity 2018.1 you can use
    UnityWebRequestAssetBundle.GetAssetBundle


    If you're loading from StreamingAssets use
    LoadFromFile(Async)
    . From the table you can read out that for Uncompressed bundles loading with LoadFromFile will not use any extra memory and the performance is reading from disk. (Not sure if that works on Android because it is inside the jar.)
     
    Last edited: Oct 26, 2018