Как повысить FPS в Unity: эффективная оптимизация с Batching
Для кого эта статья:
- Разработчики игр, особенно начинающие и промежуточные
- Ученики курсов по программированию и тестированию
Специалисты по оптимизации производительности в игровой индустрии
Разработка игр на Unity порой напоминает схватку с невидимым противником — производительностью. Когда ваша игра начинает тормозить на устройствах пользователей, каждый draw call становится на счету. Именно здесь на сцену выходит герой оптимизации — Unity Batching. Эта технология может стать решающим фактором между плавным геймплеем и slideshow-презентацией из фреймов. Готовы превратить тысячи разрозненных вызовов отрисовки в эффективные пакеты данных? Давайте разберём, как правильно "подружить" ваш проект с батчингом и заставить GPU работать с максимальной отдачей. 🚀
Оптимизация игровых проектов требует технического понимания и практического опыта — то же самое необходимо хорошему тестировщику. На Курсе тестировщика ПО от Skypro вы изучите методологии выявления проблем производительности, научитесь создавать тест-кейсы и использовать профессиональные инструменты анализа. Эти навыки применимы как в геймдеве, так и в любой другой сфере разработки, что делает профессию тестировщика универсальным стартом в IT-индустрии.
Что такое Unity Batching и почему это критично для производительности
Unity Batching — это процесс объединения нескольких объектов в один вызов отрисовки (draw call). Каждый раз, когда Unity отправляет данные на GPU, происходит определённый обмен информацией между CPU и графическим процессором. Этот обмен создаёт небольшие, но заметные задержки, особенно когда таких вызовов тысячи.
Проблема в том, что даже простые игры могут содержать сотни или тысячи объектов. Без оптимизации каждый из них требует отдельного draw call, что приводит к так называемому "CPU bottleneck" — ситуации, когда процессор не успевает подготавливать данные для графического процессора.
Алексей Петров, технический директор игровых проектов
Недавно наша команда разрабатывала мобильную стратегию с большими армиями на поле боя. На тестовой сцене с 1000+ юнитами производительность упала до неприемлемых 15 FPS. Профилирование показало, что основная проблема — количество draw calls, которое доходило до 3000+ на кадр.
Мы начали с внедрения Static Batching для элементов ландшафта и зданий, что сразу сократило количество вызовов примерно на 40%. Затем применили Dynamic Batching для однотипных юнитов, сгруппировав их по типам. Это дало ещё 30% снижения.
Критическим моментом стала оптимизация материалов — унификация шейдеров и текстур позволила Batching работать ещё эффективнее. В результате мы вышли на стабильные 60 FPS даже на средних устройствах, а количество draw calls сократилось до 400-500. Правильная настройка батчинга буквально спасла проект.
Batching решает эту проблему, объединяя объекты с одинаковыми характеристиками (материалы, шейдеры, текстуры) в один пакет данных. Вместо отправки множества маленьких пакетов информации, Unity отправляет один большой пакет, значительно уменьшая нагрузку на CPU.
| Сценарий | Без Batching | С Batching | Прирост производительности |
|---|---|---|---|
| 100 статических объектов | 100 draw calls | 1-5 draw calls | До 95% |
| 500 динамических объектов | 500 draw calls | 20-50 draw calls | До 90% |
| Открытый ландшафт с растительностью | 1000+ draw calls | 100-200 draw calls | До 80% |
| UI элементы | 50+ draw calls | 5-10 draw calls | До 80% |
Критичность батчинга для производительности сложно переоценить. Вот основные преимущества:
- Снижение нагрузки на CPU, что особенно важно для мобильных устройств с ограниченными ресурсами
- Увеличение FPS и стабильность работы игры
- Уменьшение энергопотребления, что критично для мобильных игр
- Возможность размещать больше объектов на сцене без потери производительности
- Сокращение времени загрузки уровней
Важно понимать, что батчинг — это не волшебная таблетка. Он имеет свои ограничения и условия применения, которые необходимо учитывать для достижения максимальной эффективности. 🔍

Типы Batching в Unity: Static, Dynamic и GPU Instancing
Unity предлагает три основных подхода к оптимизации отрисовки через батчинг, каждый из которых имеет свои сильные стороны и ограничения. Понимание этих различий поможет выбрать правильную стратегию для конкретного проекта. ⚙️
Static Batching
Static Batching предназначен для неподвижных объектов, которые никогда не изменяют своё положение, вращение или масштаб. При использовании этого типа батчинга Unity объединяет геометрию статических объектов в более крупные меши во время сборки проекта.
Преимущества Static Batching:
- Наиболее эффективное сокращение draw calls
- Минимальная нагрузка на CPU во время выполнения
- Работает с любыми шейдерами
- Может объединять объекты с разной геометрией, но одинаковыми материалами
Ограничения:
- Требует больше памяти, так как дублирует вершинные данные
- Применим только к неподвижным объектам с флагом "Static"
- Увеличивает размер сборки
Dynamic Batching
Dynamic Batching применяется к движущимся объектам. Unity автоматически группирует объекты с одинаковыми материалами в один draw call, даже если объекты двигаются или меняют свои параметры.
Преимущества Dynamic Batching:
- Работает с движущимися объектами
- Не требует ручной настройки (активирован по умолчанию)
- Динамически адаптируется к изменениям сцены
- Не увеличивает использование памяти
Ограничения:
- Эффективен только для объектов с небольшим количеством вершин (≤300 для объектов без скиннинга, ≤900 для объектов со скиннингом в новых версиях Unity)
- Требует идентичные материалы и шейдеры
- Потребляет CPU-ресурсы для вычисления трансформаций
- Не работает с объектами, использующими разные значения Material Property Blocks
GPU Instancing
GPU Instancing позволяет рендерить множество копий одного и того же меша с разными параметрами трансформации за один draw call. Этот подход перекладывает нагрузку с CPU на GPU.
Преимущества GPU Instancing:
- Эффективно работает с большим количеством одинаковых объектов
- Поддерживает индивидуальные параметры для инстансов (цвет, масштаб и т.д.)
- Снижает нагрузку на CPU
- Работает как со статическими, так и с динамическими объектами
Ограничения:
- Требует идентичную геометрию (один и тот же меш)
- Нужны шейдеры с поддержкой инстансинга
- Не все графические API поддерживают GPU Instancing в полной мере
- Может требовать ручной настройки для максимальной эффективности
| Тип Batching | Когда использовать | Требования к объектам | Влияние на память |
|---|---|---|---|
| Static Batching | Для неподвижных элементов уровня (здания, ландшафт) | Общий материал, флаг "Static" | Высокое |
| Dynamic Batching | Для небольших движущихся объектов | ≤300 вершин, идентичные материалы | Низкое |
| GPU Instancing | Для множества идентичных объектов (трава, деревья, враги) | Идентичная геометрия, поддерживаемые шейдеры | Среднее |
Выбор подходящего типа батчинга зависит от конкретных требований проекта. Часто оптимальным решением является комбинация всех трёх типов для разных элементов игры. В следующих разделах мы подробно рассмотрим настройку каждого из этих подходов. 🎮
Настройка Static Batching для неподвижных объектов сцены
Static Batching — мощный инструмент оптимизации для неподвижных элементов игрового мира. Правильная настройка этого типа батчинга может радикально улучшить производительность, особенно для сцен с большим количеством статических объектов. 🏗️
Настройка Static Batching включает несколько ключевых шагов:
1. Включение Static Batching в настройках проекта
Перед началом работы необходимо убедиться, что Static Batching активирован в настройках проекта:
- Откройте Edit → Project Settings → Player
- Перейдите во вкладку Other Settings
- Найдите раздел Rendering
- Убедитесь, что опция Static Batching включена
2. Пометка объектов как Static
Чтобы объект участвовал в Static Batching, его необходимо отметить как статический:
- Выберите объект или группу объектов в иерархии
- В инспекторе найдите выпадающее меню Static в правом верхнем углу
- Активируйте опцию Batching Static (можно также использовать Everything Static)
- Если работаете с префабами, убедитесь, что пометили все экземпляры или настроили префаб
Важно: если вы изменяете статус объектов в уже запущенной игре или в редакторе во время воспроизведения, необходимо вызвать StaticBatchingUtility.Combine() для пересчёта батчей.
3. Организация материалов и шейдеров
Объекты будут объединены в один батч только если используют один и тот же материал. Оптимизация материалов критична для эффективного батчинга:
- Используйте общие материалы для объектов одного типа
- Создавайте атласы текстур вместо отдельных текстур
- Избегайте ненужных вариаций шейдеров
- Рассмотрите возможность использования материалов с несколькими текстурными каналами
Пример эффективной организации материалов для уровня:
- Building_Material — один материал для всех зданий с атласом текстур
- Terrain_Material — общий материал для ландшафтных элементов
- Props_Material — материал для декоративных элементов
4. Структурирование иерархии объектов
Для максимальной эффективности Static Batching важно правильно организовать объекты в иерархии:
- Группируйте объекты с одинаковыми материалами в отдельные родительские объекты
- Избегайте глубоких вложенностей в иерархии для статических объектов
- Рассмотрите возможность использования пустых GameObject в качестве контейнеров для логической группировки
5. Проверка эффективности Static Batching
После настройки необходимо убедиться, что батчинг работает эффективно:
- Включите Stats панель в игровом режиме (Window → Analysis → Profiler)
- Обратите внимание на показатели Batches и Saved by batching
- Используйте Frame Debugger (Window → Analysis → Frame Debugger) для анализа отдельных draw calls
- Профилируйте производительность до и после применения Static Batching
Марина Соколова, ведущий технический художник
В одном из моих VR-проектов мы столкнулись с серьезной проблемой производительности. Сцена представляла собой музей с сотнями детализированных экспонатов, и FPS падал до недопустимых значений, что вызывало дискомфорт у пользователей.
Изначально каждый экспонат был смоделирован отдельно, с уникальными материалами. Профилирование показало более 2000 draw calls, что было неприемлемо для VR.
Мы полностью пересмотрели подход к организации сцены. Первым шагом стало объединение всех текстур в несколько атласов: один для металлических экспонатов, один для деревянных, и так далее. Затем все статические объекты были помечены как Batching Static.
Ключевой момент — мы переработали материалы так, чтобы использовать всего 5 основных шейдеров вместо десятков. Для некоторых визуальных эффектов применили Material Property Blocks, что позволило сохранить вариативность внешнего вида без потери возможности батчинга.
Результат превзошел ожидания: количество draw calls сократилось до 150, а FPS увеличился в 4 раза. VR-опыт стал плавным и комфортным, при этом визуальное качество практически не пострадало.
6. Типичные проблемы и их решения
При настройке Static Batching могут возникать следующие проблемы:
- Проблема: Объекты не объединяются в батчи Решение: Проверьте, что они используют идентичные материалы и все помечены как Static
- Проблема: Высокое потребление памяти Решение: Оптимизируйте геометрию объектов, рассмотрите возможность использования LOD
- Проблема: Низкая производительность при большом количестве батчей Решение: Унифицируйте материалы, используйте атласы текстур
- Проблема: Объекты с разной геометрией не объединяются Решение: Убедитесь, что они используют идентичный материал
7. Специальные случаи использования Static Batching
В некоторых ситуациях требуется особый подход к Static Batching:
- Большие открытые миры: Разделите мир на секции с отдельными статическими батчами
- Процедурно генерируемые уровни: Используйте комбинацию Static и Dynamic Batching
- VR/AR приложения: Приоритизируйте наиболее заметные объекты для Static Batching
- Мобильные платформы: Ограничьте размер батчей для экономии памяти
Правильная настройка Static Batching требует некоторого времени и экспериментов, но результаты — значительное повышение производительности — определенно стоят этих усилий. 🚀
Оптимизация Dynamic Batching для движущихся элементов
Dynamic Batching — это решение Unity для оптимизации отрисовки движущихся объектов. В отличие от Static Batching, этот подход работает "на лету", объединяя объекты с одинаковыми материалами в один вызов отрисовки даже если они перемещаются, вращаются или масштабируются. Правильная настройка Dynamic Batching может значительно повысить производительность игр с большим количеством движущихся элементов. 🏃♂️
1. Включение и настройка Dynamic Batching
Dynamic Batching в Unity включен по умолчанию, но его нужно правильно настроить:
- Убедитесь, что опция активирована в Edit → Project Settings → Player → Other Settings → Rendering → Dynamic Batching
- Для URP/HDRP проверьте настройки в соответствующем Asset (Dynamic Batching должен быть включен в Forward Renderer)
- В SRP необходимо включить опцию в скрипте рендеринга через
DrawingSettings.enableDynamicBatching = true;
2. Понимание ограничений и требований
Для эффективной работы Dynamic Batching необходимо учитывать следующие ограничения:
- Ограничение по вершинам: объекты должны содержать не более 300 вершин (без скиннинга)
- Идентичные материалы: объекты должны использовать один и тот же экземпляр материала (не просто одинаковые)
- Совместимые шейдеры: некоторые сложные шейдеры могут отключать Dynamic Batching
- Освещение: объекты с разными настройками освещения могут не объединяться
3. Оптимизация моделей для Dynamic Batching
Для максимальной эффективности необходимо оптимизировать 3D-модели:
- Создавайте низкополигональные версии часто повторяющихся объектов
- Используйте LOD (Level of Detail) для объектов, которые видны на разных расстояниях
- Разбивайте сложные модели на более простые части для соответствия лимиту в 300 вершин
- Оптимизируйте UV-развертки для уменьшения количества вершин
Пример оптимизации модели персонажа:
- Исходная модель: 1200 вершин (не подходит для Dynamic Batching)
- Оптимизированная основная модель: 280 вершин
- Детали (оружие, аксессуары): отдельные объекты по 50-100 вершин
- Результат: возможность использовать Dynamic Batching для армии NPC
4. Управление материалами
Правильное управление материалами критично для Dynamic Batching:
- Используйте общие экземпляры материалов для всех объектов одного типа
- Применяйте Material Property Blocks для изменения свойств материала без разрыва батчинга
- Создавайте атласы текстур для разных вариаций внешнего вида
- Избегайте динамического создания материалов во время игры
Пример кода использования Material Property Blocks:
private MaterialPropertyBlock propertyBlock;
private Renderer myRenderer;
void Start() {
propertyBlock = new MaterialPropertyBlock();
myRenderer = GetComponent<Renderer>();
}
public void ChangeColor(Color newColor) {
propertyBlock.SetColor("_Color", newColor);
myRenderer.SetPropertyBlock(propertyBlock);
}
5. Оптимизация скриптов для совместимости с Dynamic Batching
Некоторые операции в скриптах могут разрушать батчинг. Вот что следует учитывать:
- Избегайте частого изменения материалов через
renderer.material(это создает копии) - Используйте
renderer.sharedMaterialдля доступа без создания копий - Кэшируйте ссылки на компоненты Renderer вместо их частого получения
- Применяйте пулинг объектов вместо создания/уничтожения для динамических элементов
6. Мониторинг эффективности Dynamic Batching
Для оценки эффективности Dynamic Batching используйте следующие инструменты:
- Frame Debugger: для визуального анализа батчей (Window → Analysis → Frame Debugger)
- Profiler: для отслеживания количества draw calls и батчей
- Stats panel: для быстрого контроля показателей в режиме игры
- Прямое тестирование: включение/отключение Dynamic Batching для сравнения производительности
7. Когда не использовать Dynamic Batching
В некоторых случаях Dynamic Batching может быть не оптимальным выбором:
- Для объектов с большим количеством вершин (>300)
- Когда GPU Instancing может быть более эффективным (много идентичных объектов)
- На платформах с ограниченным CPU (батчинг требует дополнительных вычислений)
- Для объектов с частыми изменениями материалов или шейдеров
| Ситуация | Использовать Dynamic Batching? | Альтернатива |
|---|---|---|
| Небольшие движущиеся объекты (<300 вершин) | Да | – |
| Множество идентичных объектов (армия, частицы) | Возможно | GPU Instancing |
| Сложные персонажи (>300 вершин) | Нет | LOD, оптимизация меша |
| Объекты с анимацией скиннинга | С осторожностью | GPU Instancing с анимационными текстурами |
| Объекты, требующие уникальных материалов | Нет | Material Property Blocks |
Dynamic Batching — мощный инструмент оптимизации, но требует внимательного проектирования и настройки. Правильное применение этой технологии может значительно улучшить производительность вашей игры, особенно на мобильных устройствах. 📱
Лучшие практики и распространенные ошибки при работе с Batching
Batching — мощный инструмент оптимизации, но его эффективное применение требует понимания нюансов и избегания типичных ошибок. В этом разделе мы рассмотрим проверенные практики и распространенные ловушки, которые могут подстерегать разработчиков. 🛠️
Лучшие практики при работе с Batching
1. Профилирование перед оптимизацией
- Всегда начинайте с профилирования для выявления реальных проблем
- Используйте Unity Profiler для определения узких мест производительности
- Отслеживайте количество draw calls и батчей на разных устройствах
- Оптимизируйте в первую очередь те сцены, где производительность критична
2. Комбинирование разных типов Batching
- Используйте Static Batching для неподвижного окружения
- Применяйте Dynamic Batching для небольших движущихся объектов
- Внедряйте GPU Instancing для множества одинаковых объектов
- Разработайте стратегию батчинга для каждого типа объектов в вашей игре
3. Эффективная организация материалов
- Создавайте атласы текстур вместо отдельных изображений
- Используйте как можно меньше уникальных материалов
- Настраивайте материалы через Material Property Blocks
- Применяйте систему категоризации материалов для удобства управления
4. Систематический подход к оптимизации
- Начинайте с крупных объектов и часто повторяющихся элементов
- Оптимизируйте пропорционально влиянию на производительность
- Документируйте подход к батчингу для команды
- Внедряйте автоматизированные тесты производительности
5. Оптимизация для конкретных платформ
- Учитывайте ограничения целевых платформ (особенно мобильных)
- Настраивайте параметры батчинга в зависимости от мощности устройств
- Создавайте различные конфигурации для высоко- и низкопроизводительных устройств
- Тестируйте на реальном железе, а не только в эмуляторах
Распространенные ошибки и их решения
1. Ошибка: Неправильное использование материалов
Симптом: Объекты не объединяются в батчи, несмотря на одинаковые текстуры.
Решение: Убедитесь, что объекты используют один экземпляр материала, а не просто визуально идентичные материалы. Используйте renderer.sharedMaterial вместо renderer.material.
2. Ошибка: Игнорирование ограничения на количество вершин Симптом: Dynamic Batching не работает для некоторых объектов. Решение: Проверьте количество вершин в моделях. Для Dynamic Batching лимит составляет около 300 вершин. Оптимизируйте модели или разбейте их на части.
3. Ошибка: Избыточное использование уникальных шейдеров Симптом: Большое количество материалов не батчится, несмотря на идентичные текстуры. Решение: Унифицируйте шейдеры, используйте универсальные шейдеры с переключателями функций вместо множества специализированных.
4. Ошибка: Динамическое создание материалов Симптом: Производительность падает со временем, количество батчей уменьшается. Решение: Избегайте создания новых материалов во время игры. Используйте пулы предварительно созданных материалов или Material Property Blocks.
5. Ошибка: Неправильная маркировка объектов Симптом: Static Batching не работает для статических элементов сцены. Решение: Убедитесь, что все неподвижные объекты помечены флагом "Static" в инспекторе, конкретно "Batching Static".
6. Ошибка: Избыточное использование вложенных объектов Симптом: Объекты не объединяются в батчи, несмотря на идентичные материалы. Решение: Упростите иерархию объектов, используйте более плоскую структуру для статических элементов.
7. Ошибка: Игнорирование влияния освещения Симптом: Батчинг работает неэффективно в сценах со сложным освещением. Решение: Используйте запеченное освещение для статических объектов, унифицируйте параметры освещения для групп объектов.
Продвинутые техники оптимизации
1. Комбинирование мешей вручную
- Используйте
CombineMeshes()для программного объединения мешей - Создавайте LOD-системы с разной степенью объединения
- Применяйте ручное объединение для критически важных частей сцены
2. Использование сцен-компонентов
- Разделите большие уровни на подсцены для оптимизации батчинга
- Управляйте загрузкой и выгрузкой частей уровня
- Оптимизируйте батчинг в каждой подсцене отдельно
3. Автоматизация проверок батчинга
- Создайте редакторные скрипты для анализа эффективности батчинга
- Внедрите автоматические проверки в процесс сборки
- Разработайте инструменты для визуализации батчей в сцене
Чек-лист для оптимизации Batching
Используйте этот чек-лист для проверки эффективности батчинга в вашем проекте:
- ✅ Все неподвижные объекты помечены как Static
- ✅ Материалы унифицированы и используют минимум уникальных шейдеров
- ✅ Динамические объекты оптимизированы по количеству вершин
- ✅ Используются атласы текстур вместо отдельных текстур
- ✅ Для модификации материалов применяются Material Property Blocks
- ✅ GPU Instancing настроен для множества идентичных объектов
- ✅ Проведено профилирование до и после оптимизации
- ✅ Проект протестирован на целевых платформах
- ✅ Документирован подход к батчингу для команды
- ✅ Настроена система мониторинга производительности
Эффективное использование батчинга — это не разовое мероприятие, а постоянный процесс. Регулярно анализируйте производительность, экспериментируйте с разными подходами и адаптируйте стратегию оптимизации под конкретные требования вашего проекта. 🎯
Понимание и правильное применение батчинга — один из ключевых факторов, отличающих профессиональную разработку от любительской. Эта техника не просто улучшает производительность, но и позволяет создавать более сложные, насыщенные и впечатляющие игровые миры без ущерба для FPS. Начните с базовых принципов, постепенно внедряйте продвинутые методики и помните: каждый сэкономленный draw call — это шаг к более плавной и отзывчивой игре, которая будет работать на большем количестве устройств. Инвестиция времени в оптимизацию батчинга окупится многократно на всех этапах жизненного цикла вашего проекта.
Читайте также
- Unity: как создать и опубликовать игру в App Store и Google Play
- 5 проверенных способов реализации движения персонажа в Unity
- Создаем онлайн-игры в Unity: пошаговое руководство для новичков
- Разработка идеального UI в Unity: ключ к захватывающим играм
- Создание и настройка игровых объектов в Unity: руководство для начинающих
- Unity: мощный движок для разработки игр любой сложности
- Мультиплеер в Unity: создание онлайн-игр от основ до реализации
- Project Settings в Unity: полная настройка и оптимизация проекта
- Как добавить ассеты в Unity: пошаговое руководство для новичков
- Как заставить объекты вращаться в Unity: практическое руководство