Часть 1. Легкость рендеринга: Оптимизация графики
Самое простое с чего вы можете начать свою оптимизацию, так это с оптимизации графики! На сколько мы все знаем графика в играх составляет не малую ценность, но за эту ценность приходится платить ресурсами компьютера. Дабы это избежать разработчики прибегают к некоторым ухищрениям, вот некоторые из них:
- LOD (Уровни детализации): Уровни детализации представляют собой разные версии одного и того же объекта с разным количеством полигонов. В Unity вы можете настроить LOD для моделей в окне Inspector. Во время рендеринга движок автоматически переключается между разными уровнями детализации в зависимости от расстояния до камеры, что снижает нагрузку на графический процессор.
- Occlusion Culling (Сокрытие): Этот метод оптимизации заключается в автоматическом скрытии объектов, находящихся за другими объектами, которые блокируют их от камеры. Unity автоматически определяет, какие объекты можно скрыть, что уменьшает количество объектов, подлежащих рендерингу.
- Baked Lighting (Запеченное освещение): Запеченное освещение предварительно рассчитывается для сцены в редакторе перед запуском приложения. Это снижает вычислительную нагрузку в реальном времени, поскольку освещение уже сохранено в текстурах.
Так же давайте поговорим про материалы. По ним у нас на канале уже есть подробная статья. Следует не забывать по возможности применять к нескольким объектам 1 и тот же материал. Это значительно поможет ускорить отрисовку всех объектов и подарить пару лишних FPS. Так же не стоит включить в материале специальную логическую переменную чтобы все материалы отрисовывались напрямую графическим ядром, а не проходили сперва через ЦП. Данную функцию можно включить в Стандарте/URP/HDRP, находится она напрямую на материале, вот тут:
Часть 2. Оптимизация кода: Улучшение производительности
Оптимизация кодя всегда являлась для разработчиков большой проблемой и головной болью. Ведь нужно не только составить и написать грамотный код, но и последствии его оптимизацию! Оптимизацию кода можно проводить разными методами. Первый ухищрения на проверку здоровья, вот пример такого кода:
public void TakeDamage(float damage)
{
if (health > 0)
{
health -= damage;
_zombieMovable.animator.SetTrigger("TakeDamage");
if (health <= 0)
Death();
}
else
Death();
}
Как мы тут можем видеть, мы дважды проверяем общее количество здоровья и если оно по итогу меньше или равно 0 то вызываем функцию "Death()". Данная схема помогает нам избежать визуальных багов при использовании HP баров а так же отказаться от использования постоянных обновлений!
Так же применяются и другие методы оптимизации кода, вот основные:
- Object Pooling (Пул объектов): Вместо создания и уничтожения объектов по мере необходимости, используйте пул объектов для их переиспользования. Это сокращает частоту сборки мусора и улучшает производительность.
- Multithreading (Многозадачность): Unity поддерживает многозадачность через C# Job System. Выделите задачи, которые могут выполняться параллельно, и используйте Job System для распределения их по нескольким потокам, повышая производительность.
- GPU Instancing (Экземпляры на GPU): Этот метод позволяет рендерить множество однотипных объектов за один раз, минимизируя нагрузку на процессор и улучшая производительность.
Часть 3. Работа с ассетами: Эффективное управление ресурсами
Не пренебрегайте настройкой даже текстур! Это очень важный момент ведь в Unity уже есть понятный и быстрый инструмент для их настройки:
Так же не стоит пренебрегать системами оптимизации из магазина активов Unity. В нашем телеграмм канале мы выложили список активов которые наиболее рекомендуем для оптимизации проекта! Так же используйте методы что мы привели ранее, и помните что настройка текстур не добавляет вам FPS, но значительно упрощает их отрисовку!
- Texture Compression (Сжатие текстур): Используйте сжатие текстур, такое как ETC2, ASTC, или DXT, чтобы уменьшить объем памяти, занимаемый текстурами на диске и в памяти устройства.
- Asset Bundles (Пакеты ресурсов): Группируйте ресурсы в бандлы и загружайте их по требованию, снижая нагрузку на память и ускоряя начальную загрузку приложения.
- Addressables System (Система адресуемых ресурсов): Позволяет загружать и выгружать ресурсы динамически по ключу, что упрощает управление ресурсами в больших проектах.
Часть 4. Оптимизация сцен: Управление элементами уровней
Оптимизация сцен, наиболее эффективный метод добавление лишних FPS вам в проект. К примеру можно прибегнуть сразу к инструментам Unity, и заранее настроить карту света, карту визуального процесса и общую карту графики. Кстати последняя настраивается до безобразия просто, вам всего лишь нужно перейти по пути "Edit/Project Settings/Quality" и там уже настроить нужную вам графику для каждых платформ отдельно!
Так же не стоит пренебрегать настройкой самой ресурсоёмкой части всех проектов, AOT. Данные тень прекрасно добавляют тени но и кушают производительности столько же. Их грамотную настройку вы сможеет провести двумя способами, первый через ваш файл графики если вы используете URP/HDRP либо же если у вас стандартный набор графики то вам следует пройти по пути "Edit/Project Settings/Burst AOT Settings" и тут уже произвести настройку.
Так же не пренебрегайте использованием методов которые мы указали ниже:
- Culling Mask (Маскировка объектов): Используйте маски слоев для исключения невидимых объектов из рендеринга и уменьшите количество вызовов графического процессора.
- Static Batching (Статическое объединение): Объединяйте статические объекты в один большой объект для уменьшения вызовов графического процессора при рендеринге.
- Asynchronous Scene Loading (Асинхронная загрузка сцен): Загружайте сцены асинхронно для предотвращения простоев в процессе загрузки и обеспечения более плавного взаимодействия с пользователем.
Часть 5. Специализированные методы: Техники, применяемые студиями
Тут мы вам привели примеры оптимизаций которые очень часто используют студии для оптимизации своих проектов:
- Data-Oriented Technology Stack (DOTS): Эта архитектура использует ECS и C# Job System для эффективного управления данными и выполнения задач, что повышает производительность в многозадачных сценариях.
- Shader Optimization (Оптимизация шейдеров): Пересматривайте и оптимизируйте пользовательские шейдеры для достижения максимальной производительности без ущерба для визуального качества.
- Job System и Burst Compiler: Используйте C# Job System для создания многозадачных вычислений и компилятор Burst для оптимизации выполнения кода, повышая производительность.
Применение самого эффективного метода: DOTS
- Включите DOTS: В настройках проекта Unity в разделе "Player", включите DOTS и установите необходимые пакеты.
- Перепишите код: Переопределите ваш код с использованием ECS. Разделяйте данные и логику, используя компоненты и системы.
- Используйте Job System: Определите задачи, которые могут выполняться параллельно. Используйте C# Job System для распределения этих задач по нескольким потокам.
- Оптимизируйте шейдеры: Пересмотрите и оптимизируйте шейдеры вашего проекта, учитывая особенности DOTS.
- Тестирование и профилирование: После внесения изменений, тщательно тестируйте и профилируйте проект для подтверждения улучшений в производительности.
Применение DOTS требует внимательного отношения к структуре вашего проекта и может потребовать значительных изменений в коде. Однако, с правильным использованием, DOTS может обеспечить значительный прирост производительности вашей игры в Unity.