Search Unity

Why the asset bundle slow in StreamingAssets on android device?

Discussion in 'Editor & General Support' started by watsonsong, Apr 29, 2016.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I am loading the resource in Editor using AssetDatabase is fast, but when I export the assetbundle, copy them into StreamingAssets, and load them using WWW on android device, it really very slow make my game can not play.
    I see many people copy them asset bundle from StreamingAssets to persistentData path at the first time when the application launch, is it useful to speed up the load time, and why is it?
    Thank you~
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    Hey,

    What platform are you building for? Only Android?
    Also, did you measure your game's performance using the profiler? what takes most of the time?

    On Android, your game is deployed to the device in an .apk file. This is essentially a zipped file with some internal structure. While deploying your game with StreamingAssets, these files are actually stored inside the .apk (e.g: zipped).

    In order to access them, Unity allows you to easily access the bundles under streaming assets using the WWW class. Internally, it probably uses some Android APIs for accessing these files (AssetManager?) which probably have some overhead.

    What we do, in order to directly access our asset bundles under StreamingAssets, is to add native android code that copies the bundles from streaming assets to another folder that is directly accessible from code (using System.IO.File), and then we can load them directly. This actually runs pretty quick (although our bundles are very small in size, so YMMV).
     
  3. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    Hi, @liortal
    I want to check this method, copy the AssetBundle from StreamingAssets to other folder.
    It takes time when the user first launch, and take twice space than normal. I know many game do this way, but I want to find is there any good API to process it to avoid this copy?
     
  4. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    As i said, you can still use the WWW class (WWW.LoadFromCacheOrDownload). It knows how to handle files in StreamingAssets. Internally, it may do the same thing (copy the files out) though i am not sure.
     
  5. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    I am using WWW.Load data from StreamingAssets, but it very slow.
     
  6. ForceMagic

    ForceMagic

    Joined:
    Feb 27, 2015
    Posts:
    38
    It is better to copy it outside of the StreamingAssets because on Android it's inside a Jar file, so there is an additionnal it to uncompress it.

    But even there, overall file access on Android seems pretty slow, cause us to have slow loading time when loading data from files.
     
  7. Deleted User

    Deleted User

    Guest

    If you go with WWW.LoadFromCacheOrDownload(), it will uncompress the file and store it in the cache folder on the device first, then load the cached file instead.
     
  8. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    508
    Just to clarify - files in StreamingAssets folder are not compressed with zip and packaged as raw data to apk. You can see them in a transient file raw.ap_ in Temp folder while building.

    You can also use AssetBundle.LoadFromFile to load bundle directly from StreamingAssets folder.
    Depending on compression method it will be either decompressed to memory (LZMA compressed bundle with default options) or decompressed/read when loading data from it (LZ4 or uncompressed bundle).
     
  9. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    @alexeyzakharov can you explain what do you mean by "files in StreamingAssets folder are not compressed with zip" ?

    When the APK is installed, does it get uncompressed? or do the files under StreamingAssets are stored in a compressed format (inside the APK) ?
     
  10. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    508
    Hi,

    StreamingAssets are packaged into APK with -0 flag for AAPT tool (or -0 -Z for fastzip). Meaning that correspondent segment in APK is uncompressed. APK is a zip container which consists of blocks of potentially different compression types. You can use e.g. APK Analyzer to check what's compressed and what's not.
    We don not extract and store any data from APK during installation or any other time. Player's data is streamed and decompressed when requested by LoadScene or LoadAsset API. Android-specific resources are decompressed by OS.
    StreamingAssets file are considered as "foreign" files which can be used by any external code (including direct access by file descriptor) and be already compressed (video, audio).
     
  11. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    So, can i directly access files from streaming assets using Syste.IO APIs, like reafing files, etc?

    Also, on android, can i directly load an asset bundle via AssetBundle.LoadFromFile from streaming assets?
     
  12. alexeyzakharov

    alexeyzakharov

    Joined:
    Jul 2, 2014
    Posts:
    508
    No. StreamingAssets are not supported for System.IO API. You can access them only with Java code.

    Yes, since 5.3, see e.g. example for AssetBundle.LoadFromFile.
     
  13. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    Is WWW.LoadFromCacheOrDownload the best option on Android phones?
    In our game it makes our first load 3-10x slow than subsequent runs. (20-50seconds vs 5 seconds, it is dependent on LZMA vs LZ4, which is understandable)
     
  14. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    32
  15. naviln

    naviln

    Joined:
    Oct 18, 2016
    Posts:
    32
  16. tomerpeledNG

    tomerpeledNG

    Joined:
    Jul 14, 2017
    Posts:
    81
    I'm trying to use the streaming assets for shipping our app with an initial assets bundles - so that later we can patch them if needed.

    It seems that reading from the streaming assets is pretty slow, can we improve it somehow?
    It is better to ship one zip file to the streaming assets and then extract it and use WWW.LoadFromCacheOrDownload in order to read it locally?

    We're building our app for iOS and Android...
     
  17. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Which version are you using? There were improvements to that, don't remember the version exactly.
     
  18. tomerpeledNG

    tomerpeledNG

    Joined:
    Jul 14, 2017
    Posts:
    81
    2017.4.1f1
     
  19. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Then it has those improvements. On Android StreamingAssets are located inside apk and need to be pulled from it, which isn't very fast.
     
  20. NoobCoderFake

    NoobCoderFake

    Joined:
    Nov 24, 2015
    Posts:
    42
    Don't know if it's still ok to reply in this thread, but I have a related problem.
    1.Build all resources into AssetBundles;
    2.Compressed all ABs into StreamingAssets;
    3.Need to Decompress those ABs into persistentData;
    4.Use WWW www = new www(url) to read files in StreamingAssets;
    5.I use multithread to decompress since there're many files;
    6.Works fine in Normal build.
    Here is the problem: If I build a "Development build", or run this code in Editor, an exception throwed says "Create can only be called from main thread."
    Is there any way to fix it?
     
  21. Aurimas-Cernius

    Aurimas-Cernius

    Unity Technologies

    Joined:
    Jul 31, 2013
    Posts:
    3,735
    Are you using WWW from other thread? This is not supported and error you get is valid. And in non-development build it probably works by chance, likely you risk for it to crash sometimes.
     
  22. amanjiang

    amanjiang

    Joined:
    Sep 15, 2017
    Posts:
    1
    hi, I noticed that the -0 flag of AAPT only supports specifying files by extension, so how Unity deal with files in StreamingAssets without extension? Or any extension?