Asset bundles performance drop when using custom build system for Unity project on Android

106299

Lately, I ran into an issue with performance on Unity 5 (5.3.4f1 to be accurate). Our project uses remote asset bundles (that is, they are downloaded from our server). For a couple of reasons, we decided to switch to local asset bundles on some platforms (they’re inside of StreamingAssets folder but can be updated from a server if there are newer versions). And when I tested this version for the first time on Android device, it turned out that assets loading time increased dramatically. Loading an asset was taking  ~30x time more than before in some cases. Yep, I’m not exaggerating.

Oh, and we don’t use Unity for creating APK, instead, we export Unity project as Android project and then use Gradle to build it.

So, here is the full case for this issue:

  • You’re on Android
  • You load LZ4 or LZMA asset bundles from StreamingAssets folder (without using WWW.LoadFromCacheOrDownload, which doesn’t make sense anyway)
  • You don’t build your APK file using Unity – instead, you export project and use another system (Android Studio with or without Gradle or whatever)
  • It’s driving you crazy that your game runs slowly 😦

The reason

This problem only occurs when you don’t use Unity to build an APK. It means that we can build two APKs, one with Unity and one with Gradle and check if there’s a difference in some way. The right way here is to use zipalign tool from Android sdk.

Here are the shortened outputs for the APKs:

Built with Unity:

zipalign -c -v 4 built_with_unity.apk
Verifying alignment of built_with_unity.apk (4)...
      77 assets/bin/Data/Managed/Assembly-CSharp.dll (OK - compressed)
   16413 assets/bin/Data/Managed/Assembly-CSharp.dll.mdb (OK - compressed)
     ... some stuff ...
 4079796 assets/AssetBundles/asset_bundle.unity3d (OK)
     ... some more stuff ...
Verification succesfulf

Built with Gradle:


zipalign -c -v 4 built_with_gradle.apk
Verifying alignment of built_with_gradle.apk (4)...
     53 AndroidManifest.xml (OK - compressed)
    ... some stuff ...
   5563 assets/AssetBundles/asset_bundle.unity3d (OK - compressed)
    ... some more stuff ...
Verification succesfulf

Noticed the difference? Files from StreamingAssets folder (which end up in assets folder of APK) are not compressed in the first case but they are compressed in the second case and that leads to performance hit.

The solution (for Gradle)

The one who’s responsible for that is Android Asset Packaging Tool (aapt). It’s a tool that actually packages your APK, and it decides which assets are going to be compressed and which are not. Well, when we use Gradle (or another build system) instead of Unity, it’s now our responsibility to tell it that we don’t really want our asset bundles to be compressed again (they are already compressed with the different algorithm in our case).

Luckily for us, with Gradle we can tell what file extensions should not be compressed when generating APK:


android {
    ...
    aaptOptions {
        noCompress 'unity3d' // or whatever extension you use
    }
}

It’s too bad it’s not documented at all in Unity docs, hope they’ll consider adding this eventually.

 

Advertisements
Asset bundles performance drop when using custom build system for Unity project on Android

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s