📜 ⬆️ ⬇️

Unity: Build under Android or "size matters"

In some cases, it is necessary to work on reducing the size of the assembly for Android . For example, installing heavyweight APKs for mobile Internet users can cost a pretty penny. The excess size of APK in 50 MB on Google Play translates into additional difficulties with upload.



We developed a 2D game for Android on Unity , which is replete with images (most with areas of transparency) and various sounds, and faced with the problem of the size of APK. Looking ahead, I will say that having solved it and reduced the weight by 1.5 times, we received 1.5 times more downloads. Makes you think, is not it?

Trying to overcome the problem of heavyweight applications, we turned to the great documentation from Unity. It turned out that there this topic is discussed only in passing. It is mentioned which aspects influence the size of the assembly and how to influence these aspects in order to make the APK smaller, and also some specifics about the image import settings.
')
We practically did not find any other useful information on this issue on the Internet. Therefore, we conducted a small study, the results of which we hasten to share with you.

So, according to the documentation, the size of the assembly affects :
  1. Size of assets (images and sounds);
  2. Meshes and animated clips;
  3. The size of the included dll.

We didn’t work with meshes and imported animation clips, so let's start with assets.


IMAGES


Specify about the images. In our game, the principle of pixel-perfect . All images without alpha channel have a smooth gradient . The rest of the images are transparent, and the opaque areas also have a smooth gradient.

Let us analyze what contribution to the size of the ARC make images in the format of PNG and JPG .

PNG pictures


For PNG, this contribution depends on two “variables”:
  1. The size of the picture on the file system;
  2. Customize import.

We saved 3 pictures in Photoshop with settings: Compression-> Smallest / Slow, Intrelaced: No. A PNG image of 295 KB in size took 236 KB in assembly. Picture 612 Kbytes occupied 480 Kbytes. A picture of 21.2 Kbytes took 23 Kbytes (of course, with the same import settings). Progressivity is obvious.

Next, we saved the first image in Photoshop with the settings: Compression-> None / Fast, Intrelaced: Yes . Received a file of 9000 KB in size, however he added the same 236 KB in the assembly.

This confirms the words from the documentation that Unity recodes all assets to the internal format . Obviously, it approximately corresponds to the PNG format saved in Photoshop with the following settings: Compression-> Smallest / Slow, Intrelaced: No. And Unity recodes all PNGs to this format, regardless of the initial file format.

JPG pictures


Experiments have unequivocally shown that the JPG images contribute to the size of the assembly in proportion to their size . While it is not quite clear how Unity behaves if the asset is in JPG format. We saved the same (first) image in JPG and got a very small file on the file system (75 KB). However, in the assembly, he took an exorbitant 767 KB (*).

We conducted an experiment on a large number of different pictures, here I cite only a small part of the research. In other experiments, on the contrary, we managed to reduce the overall size of the assembly by converting all files from PNG to JPG.
The causes of this phenomenon have not yet been identified.
Most likely, the internal format of Unity takes place again, however, it has not yet been possible to figure out the exact principles of the interaction of Unity’s witchcraft mechanism with JPG assets.

Another way to work with JPG will be described below.

findings
  1. Apparently, Unity takes into account the format in which the image is stored, and the characteristics of the image and performs compression on any internal principles;
  2. One principle is completely unambiguous: images in the same format contribute to the size of the assembly, which is directly proportional (but NOT EQUAL) to its size on the file system .

Import settings affect the size of the assembly completely as described in the dock (the better the picture, the greater its contribution to the size of the assembly). There are no hidden features here. (No experiments have yet been carried out with other image formats.)

SOUNDS


For sounds, two import settings are important: Audio Format and ForceToMono .

WAV files take up more space in the assembly than MP3 files (the contribution to the assembly size is approximately equal to the file size). The stereo WAV file will take less space if ForceToMono = true is set . Exactly the same effect can be achieved if you convert the file to "mono" before importing (then ForceToMono will not be available in the inspector).

However, if you set the AudioFormat = Compressed import setting for the WAV file, it will take up as much space in the assembly as the corresponding top-quality MP3 file (Audacity: variable bitrate, 220-260 kbps). That is, Unity independently encodes sound in MP3 format.

For files in the same format, the principle is directly proportional to the contribution to the size of the assembly.

Other import settings do not affect the size of the assembly. They affect the amount of space occupied by sound in RAM.

AND NOW ABOUT SPECIFIC STEPS TO OUR GOAL


  1. If possible, reduce the size and quality of the original graphics files .
    (1-a) Trimming areas of transparency.
    In our game we used a lot of pictures with impressive areas of transparency around the image. Transparency areas increase the file size only by a few percent and do not really affect the size of the assembly (although cropping 102 rather big pictures saved us 2 MB). But areas of transparency increase the use of RAM (since there pictures are presented in BMP).

    Thus, the advice: to reduce the load on the RAM
    * avoid large areas of transparency in images;
    * do not form atlases with large areas of transparency, especially in NGUI.

    (But we were distracted from the main topic.)

  2. For images that do not have transparency and are displayed in the highest quality, Advanced-> RGB24 must be set in the import settings. RGBA32 for them does not make sense, but to leave Automatic Truecolor is not recommended, because (as experience has shown) it can be perceived by the system as RGBA32. And this is completely superfluous in the absence of areas of transparency (adds weight to the assembly and increases the use of RAM).
  3. Reduce the quality of images in the import settings under the scheme: 32 bit -> 24 bit -> 16 bit, making sure that the level of image quality remains within acceptable limits.
  4. Limit maxTextureSize for images for which this is possible while maintaining acceptable quality.
  5. Carefully manually delete unused assets in the Resources folders before the build process. Remember that for assets located in the Resources folders, Unity does not automatically delete them, even if they are not assigned in the Inspector.
  6. For JPG images: change the file extension to bytes and it will turn into TextAsset. After that, use the Texture2D.LoadImage () function to load the image. It should be remembered that this function loads the processor and may be inappropriate in the case of large images that need to be loaded very quickly. However, this method often helps to impressively facilitate the assembly.
  7. Reduce the size of the sound files to the minimum possible size (taking into account the quality requirements). If possible, use MP3, not WAV. But if you need the highest quality MP3s, you can use the WAV file with the import setting AudioFormat = Compressed (Unity recodes itself). If possible, use Mono instead of Stereo. For wave files - set import setting ForceToMono = true

After completing each item, it is advisable to check the effect obtained. Because in the behavior of Unity there is still some magic.

Few words about dll


The document lists a list of necessarily included in the dll assembly and calls for minimizing the number of additional dll (especially heavy). In particular, if possible, do not use System.dll (adds 2 MB to the APK). However, even if we avoid references to methods from this library, System.dll is still (as of Unity 4.5.5) included in the assembly , since it is pulled up by the mandatory Mono.Security.dll. Therefore, it turns out that the official documentation of Unity in this place is not absolutely relevant .

But the use of other (optional) dll is desirable to avoid in the name of reducing the size of the assembly.

Today we have everything. Thanks for attention!

(Please consider this material as more or less systematized results of the study, and not as a universal guide to action. I would be very happy with comments, comments, constructive criticism, objections, suggestions, additions. And, of course, I will be very happy to know what methods are used by colleagues from other companies to resolve the issue under discussion.)

Source: https://habr.com/ru/post/250873/


All Articles