Search Unity

Dealing with Large Assetbundles?

Discussion in 'iOS and tvOS' started by goodhustle, Feb 5, 2011.

  1. goodhustle

    goodhustle

    Joined:
    Jun 4, 2009
    Posts:
    310
    I'm looking into delivering graphic novel content to a Unity-based iPad app through in-app purchase. I'm not concerned with the delivery or download speed, but I haven't been able to gather much information ahead of time about restrictions on large assetbundles. If you have experience or knowledge about these, I'd appreciate any guidance you can give.

    1) Is there a maximum size limit to assetbundles?
    2) Does Unity iOS load the entire assetbundle into RAM while it is loading it?
    3) Is there an "optimal" size for loading and unloading an individual assetbundle on an iPad?
    4) For in-app purchase, if you need to deliver multiple assetbundles for a single purchase, is that possible? Or are you limited to one?

    Thanks! If this is a bad idea, and I should do an e-reader and IAP downloads through native Objective-C, feel free to tell me that as well.
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    1. No
    3. As small as possible, so you get as little pushed into ram as possible.
    4. Whatever you want to, thats all up to you as you need to download and manage these things.
     
  3. Surreal

    Surreal

    Joined:
    Dec 10, 2011
    Posts:
    29
    We are running into an issues where we are unable to load more than 20 to 25MB worth of Asset Bundles -- whether as a single bundle or broken out. This happens whether reading it locally or off the web. No useful error that shows up in logcat -- just something like this:

    W/Unity (19897): ******(url masked).unity3d at 1 percent

    W/Unity (19897): UnityEngine.Debug:Internal_Log(Int32, String, Object)

    W/Unity (19897): UnityEngine.Debug:LogWarning(Object)

    W/Unity (19897): <Start>c__Iterator1:MoveNext() (at ******\AssetBundleLoader.cs:43)

    W/Unity (19897):

    W/Unity (19897): (Filename: C Line: 0)

    W/Unity (19897):

    V/AudioPolicyManager( 75): stopOutput() output 1, stream 3, session 10

    V/AudioPolicyManager( 75): getNewDevice() selected device 0

    V/AudioPolicyManager( 75): setOutputDevice() output 1 device 0 delayMs 94 force 0

    V/AudioPolicyManager( 75): setOutputDevice() setting same device 0 or null device for output 1

    V/AudioPolicyManager( 75): releaseOutput() 1

    E/InputDispatcher( 120): channel '40685fa8 com.*/com.unity3d.player.UnityPlayerNativeActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8

    E/InputDispatcher( 120): channel '40685fa8 com.*/com.unity3d.player.UnityPlayerNativeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

    I/WindowManager( 120): WINDOW DIED Window{40685fa8 com.*/com.unity3d.player.UnityPlayerNativeActivity paused=false}

    I/ActivityManager( 120): Process com.Surreal.Character (pid 19897) has died.

    Any help is appreciated.
     
  4. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,133
    it was like 4 months ago that I did tests with this, so I may be wrong

    BUT iirc

    You really must use this function when loading asset bundles:
    http://unity3d.com/support/documentation/ScriptReference/WWW.LoadFromCacheOrDownload.html

    and that will download the asset bundle, which is essentially your content in a zip file, and then it will unzip it and 'cache' it. Once an assetbundle is already downloaded and has been cached, opening that assetBundle uses up no additional memory. You can have a few gigs of assetBundles open through LoadFromCacheOrDownload. It works just like a Resources folder, except that you downloaded it.

    However, the catch here is that Unity will download and then unzip the bundle, and it is in the unzipping that you get destroyed on an iPad device because the entire zip file must be in memory to unzip, plus some more memory to deal with the actual decompressing of the data. So in short, there is no way you can load a 400 mb assetbundle on iOS device because you can't unzip something that large on an iPad. Really 200 mb would be too much as well. You could probably get away with 50mb assetbundle chunks. But I'd do even less to be safe.

    I don't remember how much memory the unzipping process will take up. As in like, does a 50mb assetbundle take up 50mb of memory for the zip plus an additional 50-100 mb for the data that it is unzipping? Or something else? If anyone knows this I would actually be interested to know.

    As for your error, I don't know. Does it run just fine in the editor?
     
    Last edited: Apr 23, 2012
  5. GurtejKanwar

    GurtejKanwar

    Joined:
    Jul 11, 2012
    Posts:
    3
    I also had issues with crashing with asset bundles due to memory issues. My asset bundle was about 10MB in size, but it was on an older Android phone, so I don't think it had much memory available.

    Right now I'm just including the assets with the project, but I'd be interested to hear what the actual memory usage of unzipping an asset bundle is, so that I can plan around it in the future.
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    If you use WWW.LoadFromCacheOrDownload it will be decompressed on download and that factor gets negated.

    but keep in mind that especially textures tend to 'balloon' when loaded from outside (our game exploded from 55mb RAM usage at ram to over 120MB when we moved 45 524x462 gui textures uncompressed from resources to fully distinct asset bundles handled by the above cache api. Thats a major explosion and forced us to revert the decision as we didn't get anything but a more complicated workflow from it.
     
  7. Ferazel

    Ferazel

    Joined:
    Apr 18, 2010
    Posts:
    517
    I would also agree that AssetBundles are a pain, and they do not solve many problems on mobile devices where RAM is so limited.

    I my experience loading the AssetBundle loads the AssetBundle .zip into RAM. Then you need to decompress the elements out of the asset bundle (more RAM). Then on top of that there is a performance overhead with unzipping the asset out of the AssetBundle. Then you need to manage when you want to Destroy the asset by either keeping the entire AssetBundle around and use AssetBundle.Unload(true); or keep a reference to the texture around (requiring read/write on the texture, doubling size) and using AssetBundle.Unload(false);

    They are a pain and I really wish there was a better solution than AssetBundles where we could dynamically add/remove elements to the Resource system at runtime.
     
  8. goodhustle

    goodhustle

    Joined:
    Jun 4, 2009
    Posts:
    310
    I also found LoadFromCacheOrDownload works much better in terms of memory overhead. But if your application of it isn't too cacheable, keep in mind that this will also write to cache storage on mobile devices and cause a bigger hitch than just loading the assetbundle through normal means.

    There are definitely some major considerations to keep in mind when switching over to an assetbundle-based architecture, but it's pretty flexible. There are also new snazzy uncompressed assetbundles to work with! But be aware that there are tradeoffs between runtime performance, download size, memory overhead, and so forth, so you should definitely test it out thoroughly on actual hardware.