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 меньше, а также приведено немного конкретики по поводу настроек импорта изображений.
Итак, согласно документации, на размер сборки влияет :
- Размер ассетов (изображения и звуки);
- Меши и анимационные клипы;
- Размер включаемых dll.
ИЗОБРАЖЕНИЯ
Уточним насчёт изображений. В нашей игре соблюдается принцип pixel-perfect . Все изображения без альфа-канала имеют плавный градиент . Остальные изображения с прозрачностью, а непрозрачные области тоже имеют плавный градиент.Проанализируем, какой вклад в размер АРК вносят изображения в формате PNG и JPG .
Картинки в формате PNG
Для PNG этот вклад зависит от двух «переменных»:- Размер картинки на файловой системе;
- Настройка импорта.
Это подтверждает слова из документации, о том, что Unity перекодирует все ассеты во внутренний формат . Очевидно, он приблизительно соответствует формату PNG, сохранённому в фотошопе с настройками: Compression->Smallest/Slow, Intrelaced: No. И Unity перекодирует все PNG в этот формат, независимо от начального формата файла.
Картинки в формате JPG
Опыты однозначно показали, что изображения JPG вносят вклад в размер сборки пропорционально своему размеру . Пока не совсем понятно, как ведёт себя Unity в случае, если ассет находится в формате JPG. Мы сохранили ту же самую (первую) картику в JPG и получили очень маленький файл на файловой системе (75 Кбайт). Однако в сборке он занял непомерных 767 Кбайт (*).Мы проводили эксперимент на большом количестве разных картинок, здесь я привожу лишь малую часть исследований. В других экспериментах нам наоборот удавалось снизить общий размер сборки конвертированием всех файлов из PNG в JPG.
Причин этого явления выявить пока не удалось.
Скорее всего, снова имеет место внутренний формат Unity, однако точные принципы взаимодействия колдовского механизма Unity с ассетами JPG выяснить пока не удалось.
Еще один способ работы с JPG будет описан ниже.
Выводы
- Судя по всему, Unity берет во внимание и формат, в котором сохранено изображение, и характеристики изображения и выполняет сжатие по каким-либо внутренним принципам;
- Один принцип совершенно однозначен: изображения в одинаковом формате вносят вклад в размер сборки, прямо пропорциональный (но НЕ РАВНЫЙ) своему размеру на файловой системе .
ЗВУКИ
Для звуков значение имеют две настройки импорта: Audio Format и ForceToMono .Файлы в формате WAV занимают больше места в сборке, чем файлы в формате MP3 (вклад в размер сборки приблизительно равен размеру файла). Стерео WAV файл займёт меньше места, если выставить ForceToMono = true . Точно такого же эффекта можно достичь, если конвертировать файл в «моно» ещё до импорта (тогда ForceToMono не будет доступна в инспекторе).
Однако если для файла WAV установить настройку импорта AudioFormat = Compressed , то в сборке он займёт места столько же, сколько и соответствующий MP3 файл высшего качества (Audacity: variable bitrate, 220-260 kbps). То есть Unity самостоятельно кодирует звук в формат MP3.
Для файлов в одинаковом формате действует принцип прямо пропорционального вклада в размер сборки.
Остальные настройки импорта на размер сборки никак не влияют. Они влияют на количество места, занимаемое звуком в RAM.
А ТЕПЕРЬ О КОНКРЕТНЫХ ШАГАХ К НАШЕЙ ЦЕЛИ
- По возможности снижать размер и качество исходных файлов графики
.
(1-a) Обрезка областей прозрачности.
В нашей игре использовалось много картинок с внушительными областями прозрачности вокруг изображения. Области прозрачности лишь на считанные проценты увеличивают размер файла и не очень влияют на размер сборки (хотя обрезка 102х немаленьких картинок сэкономила нам 2 Мбайт). Но области прозрачности увеличивают использование RAM (поскольку там картинки представляются в BMP).Таким образом, совет: для снижения нагрузки на ОЗУ
* избегать больших областей прозрачности в изображениях;
* не формировать атласы с большими участками прозрачности, особенно в NGUI.(Но это мы отвлеклись от основной темы.)
- Изображениям, не имеющим прозрачности и отображаемым в самом высоком качестве, в настройках импорта необходимо задать Advanced->RGB24 . RGBA32 для них не имеет смысла, а вот оставлять Automatic Truecolor не рекомендуется, потому что (как показал опыт) он может восприняться системой как RGBA32. А это является совершенно лишним при отсутствии областей прозрачности (добавляет веса сборке и увеличивает использование RAM).
- Снизить качество изображений в настройках импорта по схеме: 32 bit -> 24 bit -> 16 bit, наблюдая за тем, чтобы уровень качества изображения оставался в пределах допустимого.
- Ограничить maxTextureSize для изображений, для которых это возможно с сохранением приемлемого качества.
- Тщательно вручную удалять неиспользуемые ассеты в папках Resources перед процессом сборки. Помните, что для ассетов, лежащих в папках Resources, Unity НЕ производит автоматическое их удаление, даже если они не назначены в Инспекторе.
- Для изображений JPG : сменить расширение файла на bytes и он превратится в TextAsset. После чего воспользоваться функцией Texture2D.LoadImage() для загрузки картинки. Следует помнить, что эта функция нагружает процессор и может оказаться неподходящей в случае больших картинок, которые необходимо очень быстро загрузить. Однако этот способ зачастую помогает внушительно облегчить сборку.
- Уменьшить размер звуковых файлов до минимально возможного размера (с учётом требований к качеству). По возможности использовать MP3, а не WAV. Но если нужны MP3 самого высокого качества, можно пользовать и WAV-файл с настройкой импорта AudioFormat = Compressed (Unity перекодирует самостоятельно). По возможности использовать Mono вместо Stereo. Для WAV-файлов - выставлять настройку импорта ForceToMono = true
Несколько слов о 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.