Unity: Сборка под Android или «размер имеет значение. А теперь о конкретных шагах к нашей цели

А теперь давайте поговорим об оптимизации текстур и других вещах, помогающих сделать наш билд меньше (вернее упихать в заветные 20 метров). На официальной страничке unity3d описано несколько приемов как сэкономить размер приложения этими способами. Итак, предлагается следующее.
Оптимизация используемых текстур включает в себя в первую очередь использование сжатых форматов текстур там где только возможно. Если сжатие не уменьшит занимаемый размер, то можно попробовать уменьшить размер текстуры . Что в принципе логично: зачем вам текстура размеров 2048, если у вас экран 1024х768 и она занимает места не больше, чем экран?


В новом unity3d (3.4) настройка текстуры выглядит как изображено выше. Итак, Aniso Level, Filter Mode, Wrap Mode оставляем без изменений. Начнем с Texture Type. Выставляем Advanced и радуемся: здесь можно полностью настроить текстуру как нашей душе угодно (и как позволяет редактор unity3d). Non power of 2 выставляем в ToSmaller или ToLarger . Generate Cubemap в моей 2d-игре не нужна, отключил, впрочем как и Alpha from grayscale тоже не пользуюсь за ненадобностью. Отключите Generate Mip Maps - это также позволит сэкономить на размере текстуры. Normal Map и Light Map отключаем , если не надо. Максимальный размер текстуры выставляем как можно более меньший . Что по поводу сжатия, то тут надо экспериментировать. Обычно наилучшим эффектом обладает сжатие DXT5 .

Desktop

Сжатие Занимаемая память
RGB Compressed DXT1 0.5 bpp (bytes/pixel)
RGBA Compressed DXT5 1 bpp
RGB 16bit 2 bpp
RGB 24bit 3 bpp
Alpha 8bit 1 bpp
RGBA 16bit 2 bpp
RGBA 32bit 4 bpp

iOS
RGB Compressed PVRTC 2 bits 0.25 bpp (bytes/pixel)
RGBA Compressed PVRTC 2 bits 0.25 bpp
RGB Compressed PVRTC 4 bits 0.5 bpp
RGBA Compressed PVRTC 4 bits 0.5 bpp
RGB 16bit 2 bpp
RGB 24bit 3 bpp
Alpha 8bit 1 bpp
RGBA 16bit 2 bpp
RGBA 32bit 4 bpp

Для iOS, как мы видим, выгоднее использовать PVRTC 2 bits с альфа-каналом или без (все зависит от типа вашей текстуры). Однако, искажения, которые могут присутствовать в данном типе сжатия могут кого-то не устроить, тогда следует перейти на другой тип сжатия. Выбор за вами, экспериментируйте.

Также можно оптимизировать меши и анимации. Сжатие может быть включено в настройках импорта меша (Mesh import settings).

Еще возможно уменьшить количество dll, включенных в ваш проект. Это я рассматривал в прошлой статье по оптимизации (см. ).

Поспешу заметить, что от количества импортированных ассетов размер файла нисколько зависеть не будет, поэтому, даже если у вас в ассетах лежат ненужные текстуры и т.д., то не обязательно их удалять - unity3d просто не включит их в билд. Благодаря постпроцессингу изображений в качестве текстур можно экспортировать и psd-файлы, это размер не изменит, unity3d его пережмет как ему надо.

Спасибо за внимание, если что-то непонятно или недосказано с вопросами и предложениями прошу в комментарии.

В некоторых случаях необходимо работать над снижением размера сборки для Андроид . Например, установка тяжеловесных APK для пользователей мобильного интернета может влететь в копеечку. Превышение размера APK в 50 Мб в Google Play выливается в дополнительные трудности при аплоаде.

Мы разрабатывали под Андроид на Unity 2D-игру , которая изобилует картинками (большинство с областями прозрачности) и разнообразными звуками, и столкнулись с проблемой размера APK. Забегая вперед скажу, что решив ее и снизив вес в 1,5 раза, мы получили в 1,5 раза больше скачиваний. Заставляет задуматься, не правда ли?

Пытаясь побороть проблему приложений-тяжеловесов, мы обратились к замечательной документации от Unity. Выяснилось, что там данная тема обсуждается лишь вскользь. Упоминается, какие именно аспекты влияют на размер сборки и как воздействовать на эти аспекты, чтобы сделать APK меньше, а также приведено немного конкретики по поводу настроек импорта изображений.

Итак, согласно документации, на размер сборки влияет :

  1. Размер ассетов (изображения и звуки);
  2. Меши и анимационные клипы;
  3. Размер включаемых dll.
С мешами и импортированными анимационными клипами мы не работали, потому начнем с ассетов.

ИЗОБРАЖЕНИЯ

Уточним насчёт изображений. В нашей игре соблюдается принцип pixel-perfect . Все изображения без альфа-канала имеют плавный градиент . Остальные изображения с прозрачностью, а непрозрачные области тоже имеют плавный градиент.

Проанализируем, какой вклад в размер АРК вносят изображения в формате PNG и JPG .

Картинки в формате PNG

Для PNG этот вклад зависит от двух «переменных»:
  1. Размер картинки на файловой системе;
  2. Настройка импорта.
Мы сохранили 3 картинки в Photoshop с настройками: Compression->Smallest/Slow, Intrelaced: No . Картинка PNG размером 295 Кбайт заняла в сборке места 236 Кбайт. Картинка 612 Кбайт заняла 480 Кбайт. Картинка 21,2 Кбайт заняла 23 Кбайт (естественно, при одинаковых настройках импорта). Пропроциональность очевидна.

Это подтверждает слова из документации, о том, что Unity перекодирует все ассеты во внутренний формат . Очевидно, он приблизительно соответствует формату PNG, сохранённому в фотошопе с настройками: Compression->Smallest/Slow, Intrelaced: No. И Unity перекодирует все PNG в этот формат, независимо от начального формата файла.

Картинки в формате JPG

Опыты однозначно показали, что изображения JPG вносят вклад в размер сборки пропорционально своему размеру . Пока не совсем понятно, как ведёт себя Unity в случае, если ассет находится в формате JPG. Мы сохранили ту же самую (первую) картику в JPG и получили очень маленький файл на файловой системе (75 Кбайт). Однако в сборке он занял непомерных 767 Кбайт (*).

Мы проводили эксперимент на большом количестве разных картинок, здесь я привожу лишь малую часть исследований. В других экспериментах нам наоборот удавалось снизить общий размер сборки конвертированием всех файлов из PNG в JPG.
Причин этого явления выявить пока не удалось.
Скорее всего, снова имеет место внутренний формат Unity, однако точные принципы взаимодействия колдовского механизма Unity с ассетами JPG выяснить пока не удалось.

Еще один способ работы с JPG будет описан ниже.

Выводы

  1. Судя по всему, Unity берет во внимание и формат, в котором сохранено изображение, и характеристики изображения и выполняет сжатие по каким-либо внутренним принципам;
  2. Один принцип совершенно однозначен: изображения в одинаковом формате вносят вклад в размер сборки, прямо пропорциональный (но НЕ РАВНЫЙ) своему размеру на файловой системе .
Настройки импорта влияют на размер сборки совершенно так, как это описано в доке (чем качественнее картинка, тем больший её вклад в размер сборки). Здесь скрытых особенностей не выявлено. (С другими форматами изображений эксперименты пока не проводились.)

ЗВУКИ

Для звуков значение имеют две настройки импорта: Audio Format и ForceToMono .

Файлы в формате WAV занимают больше места в сборке, чем файлы в формате MP3 (вклад в размер сборки приблизительно равен размеру файла). Стерео WAV файл займёт меньше места, если выставить ForceToMono = true . Точно такого же эффекта можно достичь, если конвертировать файл в «моно» ещё до импорта (тогда ForceToMono не будет доступна в инспекторе).

Однако если для файла WAV установить настройку импорта AudioFormat = Compressed , то в сборке он займёт места столько же, сколько и соответствующий MP3 файл высшего качества (Audacity: variable bitrate, 220-260 kbps). То есть Unity самостоятельно кодирует звук в формат MP3.

Для файлов в одинаковом формате действует принцип прямо пропорционального вклада в размер сборки.

Остальные настройки импорта на размер сборки никак не влияют. Они влияют на количество места, занимаемое звуком в RAM.

А ТЕПЕРЬ О КОНКРЕТНЫХ ШАГАХ К НАШЕЙ ЦЕЛИ

  1. По возможности снижать размер и качество исходных файлов графики .
    (1-a) Обрезка областей прозрачности.
    В нашей игре использовалось много картинок с внушительными областями прозрачности вокруг изображения. Области прозрачности лишь на считанные проценты увеличивают размер файла и не очень влияют на размер сборки (хотя обрезка 102х немаленьких картинок сэкономила нам 2 Мбайт). Но области прозрачности увеличивают использование RAM (поскольку там картинки представляются в BMP).

    Таким образом, совет: для снижения нагрузки на ОЗУ
    * избегать больших областей прозрачности в изображениях;
    * не формировать атласы с большими участками прозрачности, особенно в NGUI.

    (Но это мы отвлеклись от основной темы.)

  2. Изображениям, не имеющим прозрачности и отображаемым в самом высоком качестве, в настройках импорта необходимо задать Advanced->RGB24 . RGBA32 для них не имеет смысла, а вот оставлять Automatic Truecolor не рекомендуется, потому что (как показал опыт) он может восприняться системой как RGBA32. А это является совершенно лишним при отсутствии областей прозрачности (добавляет веса сборке и увеличивает использование RAM).
  3. Снизить качество изображений в настройках импорта по схеме: 32 bit -> 24 bit -> 16 bit, наблюдая за тем, чтобы уровень качества изображения оставался в пределах допустимого.
  4. Ограничить maxTextureSize для изображений, для которых это возможно с сохранением приемлемого качества.
  5. Тщательно вручную удалять неиспользуемые ассеты в папках Resources перед процессом сборки. Помните, что для ассетов, лежащих в папках Resources, Unity НЕ производит автоматическое их удаление, даже если они не назначены в Инспекторе.
  6. Для изображений JPG : сменить расширение файла на bytes и он превратится в TextAsset. После чего воспользоваться функцией Texture2D.LoadImage() для загрузки картинки. Следует помнить, что эта функция нагружает процессор и может оказаться неподходящей в случае больших картинок, которые необходимо очень быстро загрузить. Однако этот способ зачастую помогает внушительно облегчить сборку.
  7. Уменьшить размер звуковых файлов до минимально возможного размера (с учётом требований к качеству). По возможности использовать MP3, а не WAV. Но если нужны MP3 самого высокого качества, можно пользовать и WAV-файл с настройкой импорта AudioFormat = Compressed (Unity перекодирует самостоятельно). По возможности использовать Mono вместо Stereo. Для WAV-файлов - выставлять настройку импорта ForceToMono = true
После выполнения каждого пункта желательно проверять полученный эффект. Поскольку в поведении Unity всё же есть доля магии.

Несколько слов о dll

Документ приводит список обязательно включаемых в сборку dll и призывает минимизировать количество дополнительных dll (особенно тяжёлых). В частности, по возможности не использовать System.dll (добавляет к APK 2 Мбайт). Однако даже если мы будем избегать ссылок на методы из этой библиотеки, System.dll всё равно (по состоянию на Unity 4.5.5) включается в сборку , так как её подтягивает обязательная Mono.Security.dll. Потому, получается, что официальная документация Unity в этом месте не совсем релевантна .

А вот использования других (необязательных) dll желательно избегать во имя снижения размера сборки.

На сегодня у нас всё. Спасибо за внимание!

(Просьба рассматривать данный материал как более-менее систематизированные результаты исследования, а не как универсальное руководство к действию. Буду очень рад комментариям, замечаниям, конструктивной критике, возражениям, предложениям, дополнениям. И, конечно, несказанно рад буду узнать, какие приёмы применяют коллеги из других компаний для решения обсуждаемого вопроса.)

Теги: Добавить метки

Последний инструмент на панели инструментов terrain’а предназначен для настроек:-

Инспектор настроек

Настройки предоставлены для некоторого количества общих настроек использования и освещения, описанных ниже:-

Base Terrain

Свойство: Функция:
Pixel Error Точность преобразования между картами terrain’а (карта высот, текстуры, и т.д.) и самим сгененрированным terrain’ом.; чем выше значения, тем меньше точность, но и меньше потребление ресурсов.
Base Map Distance Максимальное расстояние, на котором текстуры земли отображаются в полном разрешении. После этого расстояния, будет использоваться композитное изображение пониженного разрешения для эффективности.
Cast Shadows Отбрасывает ли тени terrain?
Material Материал, используемый для отрисовки terrain’а. Он должен использовать подходящий шейдер, например Nature/Terrain/Diffuse (этот шейдер используется, если материал не назначен) или Nature/Terrain/Bumped Specular.
Physics Material Physic Material , используемый на поверхности terrain’а для указания его сцепления и упругости.

Tree and Detail Objects

Свойство: Функция:
Draw Должны ли отрисовываться деревья, трава и детали?
Detail Distance Расстояние (от камеры), после которого детали будут отсекаться.
Detail Density Количество объектов деталей/травы в данной условной единице площади. Можно снизить значение для снижения потребления ресурсов на рендеринг.
Tree Distance Расстояние (от камеры), за которым деревья будут отсекаться.
Billboard Start Расстояние (от камеры), начиная с которого 3D деревья начнут заменяться на спрайтовые изображения.
Fade length Расстояние перехода деревьев из 3D объектов в плоские спрайты.
Max Mesh Trees Максимальное количество видимых деревьев, которые будут представлены в качестве полноценных 3D мешей. После этого предела, деревья будут заменяться плоскими спрайтами.

Настройки ветра

Свойство: Функция:
Speed Скорость обдувающего траву ветра.
Size Размер “ряби” на травянистых областях, обдуваемых ветром.
Bending Степень наклона объектов травы под действием ветра.
Grass Tint Общий оттенок цвета, применённый к объектам травы.

Разрешение

Свойство: Функция:
Terrain Width Размер объекта tarrain’а по его оси X (в мировых единицах измерения).
Terrain Length Размер объекта tarrain’а по его оси Z (в мировых единицах измерения).
Terrain Height Разница по оси Y между значениями самой нижней и самой верхней точек карты высот (в мировых единицах измерения).
Heightmap Resolution Разрешение карты высот terrain’а в пикселях (должно быть степенью двойки плюс один, например, 513 = 512 + 1).
Detail Resolution Разрешение карты, которая определяет отдельные островки деталей/травы. Чем выше разрешение, тем меньше и более детальны будут островки.
Detail Resolution Per Patch Длина/ширина квадрата островков, отрисовываемого за один draw call.
Control Texture Resolution Разрешение карты “splatmap”, которая контролирует смешивание разных текстур terrain’а.
Base Texture Resolution Разрешение композитной текстуры, используемой на terrain’е когда вы смотрите на него с расстояния, большего чем значение Basemap Distance (см. выше).

Кнопки Heightmap Import/Export

Кнопки Import Raw и Export Raw позволяют вам установить или сохранить карту высот terrain’а в файл изображения в RAW формате оттенков серого. Файлы формата RAW могут быть созданы в сторонних приложениях для генерации ландшафта (например, Bryce), а также открыты, отредактированы и сохранены в Photoshop. Это позволяет осуществить утончённую генерацию и редактирование terrain’ов вне Unity.



В продолжение темы:
Windows

Часть вторая : "Важнейшие характеристики каждого семейства процессоров Intel Core i3/i5/i7. Какие из этих чипов представляют особый интерес" Введение Сначала мы приведём...

Новые статьи
/
Популярные