Уменьшение размера игры для iPhone - Endless Engine. Производительность - плюс! "Макияж" главного меню.
Успешно завершился второй этап оптимизации. Теперь игра занимает в 3 раза меньше места на устройстве. Параллельно я доработал главное меню. Помимо оптимизации, был проведен художественный проход — о нём пару слов чуть позже.
Оптимизация игры велась параллельно с разработкой. Создание ассетов, проектирование уровней и общая архитектура проекта строились с расчетом на минимальное потребление ресурсов при максимально симпатичном визуале. И, конечно, всё должно было работать стабильно — то есть обеспечивать 60 кадров в секунду.
Второй этап оптимизации, нацеленный на уменьшение размера билда, был спланирован на обновление.
По итогу: первая версия игры занимала 569 мегабайт.
Идеальным вариантом было бы уменьшить размер игры до 200 мегабайт, чтобы AppStore позволял скачивать её по мобильному интернету без предупреждений. Ну и, конечно, чем меньше игра занимает места на устройстве, тем лучше. Скажу сразу: цель была достигнута! Более того, получилось "прыгнуть выше головы"!
Настройка сборки
Самым первым делом нужно переключить метод сжатия с "обычного" (Default) на LZ4HC. Это самый высокий уровень сжатия и под мой проект как раз подходило. Находится эта опция в File -> Build Settings
Сжатие текстур
Львиную долю места на устройстве занимала сама игра.
Чтобы проанализировать, за что ухватиться с ножницами в первую очередь, нужно сформировать отчёт. Для этого нужно собрать билд, зайти в консоль и, нажимая на 3 точечки, выбрать Open Editor Log.
Там очень много информации, но нам нужно Build Report. Находим этот заголовок и составляем свой небольшой "план оптимизации". В подавляющем большинстве случаев именно изображения будут занимать очень много места. Если есть видео-файлы, то и они. И конечно же - музыка и звуки. Из неочевидного - сетки 3д моделей. Местами они могут оказаться более увесистыми, чем кажется.
Уменьшать размеры текстур можно прямо в Unity, и даже - нужно. Выбираем изображение и в Инспекторе во вкладке iOS (Android или другая платформа) устанавливаем "уникальные" настройки сжатия. На разных платформах - разные алгоритмы сжатия.
Опытным путём нащупывается допустимый уровень сжатия. Мне хорошо подошёл алгоритм ASTC. В нём, чем больше размер блока (максимальное 12х12, минимальное 4х4), тем больше сжатие. Но! И очевидно, артефактов тоже больше! Поэтому нужно к этому делу подходить с умом и постоянно балансировать между качеством и размером файла.
С настройкой разрешения нет никаких особенностей. Можно только выбрать алгоритм уменьшения. Хорошо подходит тот, что по умолчанию - Mitchel.
Уменьшать сразу разрешение или пытаться сжимать - вопрос не тривиальный и к каждому объекту стоит подходить индивидуально.
Шейдеры. Еще больше шейдеров!
В игре было разработано огромное количество шейдеров, которые на стадии производства версии 1.0 сэкономили много мегабайт. Это отличная практика - оптимизировать игру с помощью продуманных "кастомных" шейдеров.
Естественно, я решил пройтись с шейдерами снова.
Некоторые текстуры были черно-белыми. Какая-то часть – почти черно-белые.
Их как раз таки и нужно паковать по принципу 3 в 1. Т.е. в графическом редакторе (Photoshop/Krita/Gimp) создается пустой файл. Далее в отдельный канал Red вставляется первая текстура, в Green - вторая, а в Blue - третья.
Под готовую "карту" создается шейдер, где источник изображения не RGB, а отдельно взятый канал. Можно задействовать и альфа канал - A! Но стоит учитывать, что цвета там сжимаются по-другому. Следовательно, картинка будет отличаться от тех текстур, что лежат в RGB.
Таким образом, на выходе вместо 3-х изображений получается 1.
На тех объектах, где текстура почти чёрно-белая, я использовал "колоризацию" с помощью Vertex Color. Для этого нужно ЧБ карту множить на Vertex Color в шейдере (или смешивать как душе угодно). Сам цвет вершин можно покрасить как в 3д редакторе, так и в Unity с помощью PolyBrush.
Шейдеры и творчество
Пару слов о творчестве, как и обещал!
В ходе оптимизации возникло пару мыслей, как улучшить фактурность стен в главном меню, "подтюнить" тени и в общем сделать картинку контрастнее. Что получилось - можно видеть на заглавной картинке статьи: по стенам более живо бегают блики, передавая инопланетную фактурность. В тёмных местах более проработанная детализация теней. Задний фон теперь имеет более читаемые формы и полутона, дополнительные оттенки от освещения. Всё это, в том числе, благодаря шейдерам!
И работает лучше, и выглядит сочнее!
Сжатие музыки и звуков
Проход с "тисками" стоит сделать и по аудиофайлам. Всё делается точно так же, как и с текстурами: выбрать файл и в инспекторе настроить параметры сжатия.
Дробление крупных 3д моделей на мелкие ассеты
На этапе разработки игры все строения я моделировал отдельными цельными объектами, несмотря на то, что дом очень часто состоит из повторяющихся частей. Это нужно для наименьшего количества батчей. И всё отлично - производительность на высоте. Вот только сами сетки весят немножко тоже.
Решил оптимизировать и здесь! Поделил дома на отдельные ассеты и пересобрал заново дома. Размер билда еще немного поубавился, но само собой - производительность подупала.
Для того, чтобы этого не было, я решил данный вопрос на уровне кода: сшивать "дома" и прочие дробленые объекты снова в 1 меш в рантайме с помощью Mesh.CombineMeshes.
Всё вышло просто отлично! Размер игры поубавился, производительность повысилась снова.
Убираем лишнее в настройках проекта
Экономить, так экономить!
В настройках проекта (Edit -> Project Settings) тоже есть что вырубить, порезать, поднастроить!
Во вкладке Player в разделе Others Settings есть конфигурация. Там API Compatibility Level тоже влияет на конечный размер билда. Просто .NET Framework меньше "жрёт", чем .NET Framework 2.1.
Так же можно выставить IL2CPP Code Generation на Faster (smaller) builds.
Там же есть раздел Optimization. В нём можно поменять Managed Stripping Level на High. Весить будет игра меньше, но и редактор будет более жёстче игнорировать "неиспользуемый код". Стоит держать в уме, что могут быть (маловероятно) от такой оптимизации неожиданные неприятные сюрпризы.
В отдельной вкладке Graphics (слева) нужно убрать те шейдеры, которые не используются. Они тоже занимают объём.
По умолчанию там навалено 10 шейдеров. В зависимости от того, как используются в проекте эти шейдеры, можно сэкономить немножко места. Так же можно выключить Video на Don't include, если в игре нет никаких видеороликов.
Извращаемся в Package Manager ради 1 мегабайта
Различные установленные пакеты (Window -> Package Manager) тоже занимают место в сборке. Некоторые из них идут установленными по умолчанию в пустом проекте. Чтобы их отобразить, нужно переключить список на Packages: Built-in. Всё, что не используется в проекте, можно вырубить. Стоит предельно точно понимать, используется ли пакет в вашей игре или нет. Иначе будут ошибки.
Стоит сказать, что выключая "дефолтные" пакеты сэкономить удастся очень мало.
Что в итоге вышло.
Получилось ужать до 182 мегабайт на устройстве. Результат потрясающий!
В будущей версии игры — 1.1 будет вся эта оптимизация. В версию 1.0 поиграть на iPhone можно тут:
Спасибо за внимание!