Гайд по оптимизации мобильных игр в Unity

Гайд по оптимизации мобильных игр на Unity
Гайд по оптимизации мобильных игр на Unity

Всем привет! Меня зовут Илья, я работаю разработчиком мобильных игр на Unity вот уже несколько лет и сегодня хотел бы поделиться небольшим чек-листом (или гайдом) по оптимизации мобильных игр для начинающих. В этой статье мы коснемся как графических, так и других аспектов оптимизации "на скорую руку" когда вам нужно быстро поднять FPS ваших мобильных игр.

По большей мере речь пойдет про оптимизацию 2D игр, чтобы их можно было запустить даже на кипятильнике.

Итак, с предисловием закончили. Поехали!

Оптимизация графики и ассетов

Работа с камерой

1) Постарайтесь использовать одну камеру на сцене. Чем больше камер вы используете, тем выше нагрузка на CPU.

2) Избегайте использования пост-обработки, это серьезно увеличивает нагрузку на GPU за счет того, что движку приходится обрабатывать повторно каждый кадр при отрисовке.

4) Используйте MSAA не выше 4X на любых мобильных платформах.

5) Используйте Forward-режим рендеринга без использования HDR, чтобы снизить нагрузку на GPU.

6) Выставьте необходимые Clear Flags на камере, чтобы указать, что нужно очищать при рендеренге каждый кадр.

7) При разработке 3D игр, также настройте допустимый Clipping Planes для ограничения области прорисовки дальних объектов.

Работа с рендерингом

1) Старайтесь использовать облегченные API, как Vulkan или Metal если это возможно. Для 2D игр достаточно OpenGL 2.

2) Используйте Occlusion Culling для выгрузки объектов вне поля зрения.

3) Используйте только запеченное освещение, тени и Reflection Probes (от них лучше отказаться вовсе). Не используйте ни в коем случае Realtime расчеты.

4) Старайтесь использовать Static и Dynamic Batching для ваших объектов для объединения геометрии.

5) Старайтесь не использовать процедурные системы частиц.

6) Старайтесь по минимуму использовать анимации. Где это возможно, анимируйте объекты через ваши скрипты или, к примеру через DOTween.

7) Установите значение флага "Realtime Pixel Lights" на 0, если это возможно.

8) Выключите Soft Particles.

9) Старайтесь использовать простые шейдера с минимальным количеством инструкций.

10) Избегайте сэмплинга в Reflection Probes.

11) Используйте общий материал для ваших объектов.

12) Используйте Gamma рендеринг вместо Linear.

13) Постарайтесь использовать URP-рендеринг вместо Legacy (Built-in).

14) Постарайтесь изучить и использовать ShaderVariants в вашем проекте., для уменьшения нагрузки на GPU.

15) При добавление/удалении шейдеров в проекте, держите актуальным список Always Inculded Shaders.

16) Иногда требуется разогреть видео-чип перед стартом игры, чтобы исключить микро-фризы при первой отрисовке объекта. Для этого вы можете прогревать их в процессе загрузки игры, инициализируя объекты на сцене Preload.

Работа с ресурсами

1) Используйте Sprite атласы для интерфейсов и объединения графики в единый спрайт. Таким образом ваши объекты будут занимать меньше памяти на GPU. Желательно использовать последнюю версию инструмента для работы с атласами.

2) Постарайтесь избегать прозрачности в спрайтах.

3) Включите "Optimize Game Objects" при импорте мешей с ригом.

4) Минимизируйте количество деревьев в анимации.

5) Уменьшите количество костей и вертексов для анимации.

6) Используйте уровни отрисовки (LOD) для дальних объектов (касаемо 3D графики).

7) Избегайте Multi-Pass шейдеров.

8) Попробуйте использовать стриминг текстур.

9) Настройте оптимальные параметры для компрессии текстур, 3D моделей, анимаций и другого контента. Если есть необходимость - настройте MIPMAPS для тяжелых объектов.

10) Отключите Read/Write в импорте ассетов, где это возможно.

11) Настройте предзагрузку шейдеров, которые необходимы в геймплее.

12) Отключите все анимационные контроллеры. Включайте их только при необходимости, поскольку даже пустые Animation Controller создают нагрузку на GPU.

13) Не воспроизводите вместе Unity-анимации и DOTween анимации.

Оптимизация UI

1) Используйте Sprite атласы. Это важно!

2) Избегайте изменения на UI каждый кадр отрисовки. Лучше изучите как работают события и делайте изменения через слушатели.

3) По возможности откажитесь от Rich Text, автоматической подгонки размера текста. В идеале - лучше использовать TextMesh вместо Unity Text.

4) Не используйте автоматическую систему слоев в UI. Также постарайтесь сократить количество UI слоев до 2х.

5) Настройте материалы у вашего UI. Не используйте UI без материалов, желательно не использовать стандартные шейдера.

6) Старайтесь не использовать пустые и невидимые объекты с компонентами Image. Все они влияют на нагрузку GPU.

Оптимизация Аудио

1) Включите Straming на длинных аудио-клипах.

2) Отключите предзагрузку аудио-файлов там, где она не нужна.

3) Настройте оптимальную компрессию аудио.

4) Ограничьте хранение ссылок на аудио в памяти.

5) Настройте Bufffer size на Best perfomance.

6) Отключите все Plugins для Audio. Уменьшите количество потоков в половину от стандартного значения.

7) При правильном использовании Mixer можно снизить нагрузку на CPU, разбив отдельные звуки как дорожки микшера.

Использование Addressables вместо Asset Bundles

1) Настройте Addressables вместо Asset Bundles. Обо всех преимуществах в экономии памяти вы можете почитать на сайте Unity.

2) Избегайте использования ресурсов из директории "Resources".

3) Уменьшите размер вашей сборки при помощи CDN и последующей загрузки с него ресурсов.

Оптимизация кода

1) Не используйте бесконечные Coroutine-функции, старайтесь минимизировать их размер.

2) Используйте пулы объектов, вместо реинициализации и уничтожения объектов со сцены.

3) Используйте ваш менеджер управления состояниями. Старайтесь не использовать обновления состояния объектов через Update.

4) Старайтесь убрать все неиспользуемые ссылки в объектах. Старайтесь не использовать на глобальных объектах тяжелых ссылок.

5) Постарайтесь вручную контролировать Garbadge Collector.

6) Избегайте генеративных методов Garbadge Collector-а, таких как FindObjectsOfType.

7) Избегайте боксинга/анбоксинга в C#.

8) По возможности, старайтесь не хранить ссылки на все подряд в памяти. Для удобства, можете использовать Zenject для внедрения зависимостей.

9) Не используйте SpriteAtlas.GetSprite во избежание утечек памяти.

Оптимизация проекта

Настройка Player Settings

1) Оставьте только те Build Targets, которые вы хотите использовать.

2) Используйте IL2CPP вместо .Net компиляции при публикации вашего приложения.

3) Используйте GPU Skinning, если это возможно.

4) Не забудьте выставить флаг "static" у тех объектов на сцене, которые являются статичными.

5) В иерархии сцены, постарайтесь не использовать динамичные объекты с большим количеством дочерних или родительских объектов.

6) Включите Multithreaded rendering и Graphics Jobs в настройках проекта.

Итого

Соблюдая данный чек-лист вы сможете добиться значительного уменьшения Draw Calls, а также оптимизировать без лишних затрат ваш проект. Желательно задуматься об оптимизации вначале работы над вашим проектом, поскольку это может сэкономить вам нервы в дальнейшем.

Надеюсь, вы подчерпнули для себя что-то новое. И буду рад вашим дополнениям!

P.S. Если будет интерес, в следующих статьях могу подробнее рассказывать о каждом разделе с подробным объяснением и сравнениями.

6868
62 комментария

1. Не используйте этот чеклист пока не сделали первую игру
2. Не используйте этот чеклист пока не понимаете что значит любой из этих пунктов
3. Не думайте об оптимизации, думайте о геймплее, когда ваша игра взорвет рынок - наймёте Илью Сергеича и он оптимизирует вам игру.

23

Если заранее об оптимизации хоть чуть чуть подумать то это может сыграть на руку. Тот же Google play больше шансов даст фичеринг для более оптимизированной игры.

4

Комментарий недоступен

По возможности, старайтесь не хранить ссылки на все подряд в памяти. Для удобства, можете использовать Zenject для внедрения зависимостей.Который будет хранить тысячи лишних ссылок вместо вас (:

5

Ну на большом проекте все же это будет куда удобнее и для гейм дизайнеров и для разработчиков.

1

Делать анимации скриптами прожорливее 🤔

3

Нет, простые анимации лучше сделать кодом, а не при помощи системы анимаций Unity. Она более прожорливая

1