Методы оптимизации при разработке в Unity 3D
Производительность имеет решающее значение для мобильных игр. В этой статье я опишу подходы, которые мы использовали для оптимизации игр на основе Unity.
14К открытий15К показов
![Методы оптимизации при разработке в Unity 3D](https://media.tproger.ru/uploads/2017/10/spearfishing-mini.png)
![Аватарка эксперта Евгений Семушин](https://media.tproger.ru/uploads/2017/10/evgeny.jpg)
Евгений Семушин
руководитель компании по разработке программного обеспечения EcmaSoft
Производительность имеет решающее значение для мобильных игр. Особенно если игра сочетает в себе физику, AI (искусственный интеллект) и полностью анимированных персонажей 3D-мира. Некоторое время назад мы сделали игру под названием «Spearfishing 3D — подводная охота» для iOS. За первые полгода после релиза игра была скачана около двух миллионов раз и попала в топ-10 в категории «Игры» в разных странах мира. Одна из основных проблем, которую нам понадобилось решить, — обеспечение работы игры с 60 fps. Это стало проще с выпуском iPad и iPhone 4, но мы по-прежнему должны поддерживать как минимум 30 fps для iPhone 3G/3GS. В этой статье я опишу подходы, которые мы использовали для оптимизации игр на основе Unity.
Использование Performance Profiler
Первое место, куда нужно смотреть, когда хочется улучшить производительность — это Unity Profiler. Эта функциональность доступна в Unity Pro и позволяет анализировать проблемные места. Профайлер — бесценный инструмент. С его помощью можно определить, где возникают проблемы с частотой кадров. Для его использования запустите игру на мобильном устройстве и профайлер на PC. Когда вы запускаете игру, профайлер начинает загружать данные о производительности.
Чтобы использовать профайлер на мобильных устройствах, сделайте билд в Developer mode. Из документации Unity:
Чтобы иметь возможность подключиться к плееру, плеер должен быть запущен с помощью опции Development Build, которая находится в диалоговом окне Build Settings.
Здесь также можно отметить флажок для автоматического соединения редактора и плеера. Профайлер показывает график использования CPU во время игры. Просто подключите мобильное устройство к машине для разработки и проходите игру. Профайлер покажет все проблемы в режиме реального времени. Он разбивает активности на Rendering, Scripts, Physics, GarbageCollector, VSync и другие. В мобильных играх часто бывают проблемы с рендерингом. Иногда скачки производительности возникают в скриптах при загрузке сцены, но в этом нет ничего необычного. Некоторые скачки связаны с физикой.
Физика и искусственный интеллект
Я опишу несколько основных идей оптимизации кода физики и перейду к графике.
- Старайтесь, чтобы как можно меньше объектов двигалось одновременно. «Спящие» объекты намного дешевле.
- То же самое касается искусственного интеллекта. Если объект находится далеко от главного героя или его не видно, не запускайте скрипты искусственного интеллекта.
- Рейкасты очень дорогие. Не делайте рейкаст на каждый фрейм — попробуйте кэшировать результаты и пропустить некоторые фреймы.
- Старайтесь избегать сложных меш коллайдеров.
- Проверьте функции
Update()
. Они запускают каждый кадр и, следовательно, дорогие. Вместо этого используйтеCoroutines
.
Static batching
Это фича Unity, которая экономит много циклов CPU. Каждый раз, когда объект рендерится, происходит Draw Call — команда для CPU или GPU о том, что объект должен отрендериться. Unity запускает несколько вызовов отрисовки и накладывает их друг на друга, это и формирует сцену. Однако каждый Draw Call требует ресурсов CPU, поэтому мы хотим минимизировать их количество.
Тут и стоит использовать Batching. Он нужен для того, чтобы не делать лишние Draw Calls. Batching бывает двух видов: статический и динамический. Статический дает лучшую производительность, поэтому мы всегда стараемся использовать его.
Чтобы эффективно применять Static Batching, используйте как можно меньше различных материалов. Для этого скомбинируйте все материалы в одну большую текстуру. Последний шаг — добавить Lightmap к сцене. Поскольку мы практически не используем память для текстуры объектов, можно сделать довольно подробную Lightmap, и проблем с памятью не возникнет.
Для использования Static Batching поставьте флажок Static в свойствах объекта. Его можно использовать только для объектов, которые не перемещаются, не вращаются и не масштабируются в сцене.
Dynamic Batching
Для не статических объектов можно использовать Dynamic Batching. Объекты с Dynamic Batching требуют определенные ресурсы на каждую вершину, поэтому он применяется только к мешам, содержащим менее 900 вершин. Наш шейдер использует Vertex Position, UV и Colors. Таким образом, у нас может быть до 300 вершин на объект.
Некоторые полезные советы из руководства Unity:
- Динамический батчинг связан с дополнительной нагрузкой для каждой вершины, так что он применим только к мешам, в сумме содержащим менее 900 вершин.
- Если ваш шейдер использует Vertex Position, Normal и единственный UV, то вы можете батчить до 300 вершин; тогда как если шейдер использует Vertex Position, Normal, UV0, UV1 и Tangent, то только 180 вершин.
- Не масштабируйте. Объекты с масштабом (1,1,1) и (2,2,2) не будут батчиться.
- Равномерно масштабированные объекты не будут батчиться с неравномерно масштабированными.
- Использование различных материалов приведет к сбою батчинга.
- Объекты с Lightmap имеют дополнительный (скрытый) параметр материала: смещение/масштаб в Lightmap, поэтому объекты с Lightmap не будут батчиться.
Заметьте: если у объекта есть анимация, но при этом есть часть, которая никогда не двигается, можно отметить эту часть как статическую, и она не будет мешать анимации.
14К открытий15К показов