Сборка и оптимизация
Build Settings, Profiler, бюджет кадра — от готового прототипа к билду.
Хорошая новость: сборка билда — обычно одна-две кнопки. Плохая: оптимизация — это бесконечная работа, в которой большие выигрыши получаются от понимания где именно тратится время.
Build Settings
File → Build Profiles (в Unity 6 — новое имя; раньше Build Settings):
- Platform — Windows / macOS / Linux / Android / iOS / WebGL / Console.
- Scenes in Build — список сцен (по индексу).
SceneManager.LoadScene(0)— первая. - Build или Build And Run — собирает в указанную папку.
Для каждой платформы свои Player Settings (Edit → Project Settings → Player):
- Имя продукта, иконка, splash screen.
- Scripting Backend: Mono vs IL2CPP (см. главу про стек).
- API Compatibility Level — .NET Standard 2.1 (рекомендуется).
- Managed Stripping Level — насколько агрессивно линкер выкидывает “неиспользуемый” код.
Managed Stripping = High может выкинуть код, который используется только через рефлексию или
Unity Events. Если после билда что-то “пропадает”, попробуйте Low/Disabled. Долгосрочное решение —
link.xml или атрибут [Preserve] на нужных типах.
Бюджет кадра
Для 60 FPS у вас 16.6 мс на кадр. Из них:
- 2–4 мс обычно уходит на рендеринг сцены и постпроцесс (GPU).
- 2–6 мс — physics + animation + ваши скрипты (CPU).
- Остаток — buffer, GC, VSync.
На 30 FPS — 33.3 мс. Для VR с 90 FPS — 11.1 мс и без права на просадки.
Profiler
Window → Analysis → Profiler. Запустите Play, остановитесь на интересном кадре. Смотрите:
- CPU Usage — стек вашего кода: что съело время.
- GPU Usage — какой проход рендера сколько занял.
- Rendering — количество draw call’ов, треугольников, batches.
- Memory — общая память, allocations.
Главный враг — GC Alloc в Update. Каждая аллокация (new string, new List<>, Vector3.ToString())
рано или поздно вызовет паузу сборщика мусора. Цель — 0 байт аллокаций в стабильном gameplay.
// Плохо: каждый кадр строит новую строку и LINQ-цепочку
private void Update() {
var alive = enemies.Where(e => e.IsAlive).ToList();
label.text = "Враги: " + alive.Count;
}
// Хорошо: счётчик ведётся событиями, строка — через struct-формат
private int _aliveCount;
private static readonly System.Text.StringBuilder _sb = new();
private void Update() {
_sb.Clear();
_sb.Append("Враги: ").Append(_aliveCount);
label.SetText(_sb); // TMP принимает StringBuilder без аллокаций
}
Frame Debugger
Window → Analysis → Frame Debugger. Останавливает рендеринг на любом draw call и показывает: какой
меш, материал, текстуры, render target. Лучший способ понять, почему 800 draw call’ов на простой
сцене.
Типичные находки:
- Одинаковые материалы, которые не батчатся (instance-копии материалов).
- UI-канвасы, которые пересобираются каждый кадр.
- Десятки маленьких источников света с теневыми проходами.
- Постпроцесс, отключаемый только в одной из сцен.
Workflow профайлера — CPU, GPU, Rendering, Memory
Профайлер — это не “включил и смотришь”. Эффективный workflow:
- Подготовьте target-сцену — пусть она представительна для real gameplay (битва, перемещение по миру). Прогрейте 10 секунд, чтобы GC stabilized.
- Откройте Profiler в
Standaloneрежиме (Profiler → Edit → Profile Standaloneповерх dev build на target-устройстве). Editor-профайлинг скрывает многие реальные проблемы. - Включите Deep Profile только если общий показывает hot path в “unknown” — Deep даёт детализацию ценой ×3–10 overhead.
- Изучите CPU Usage сначала — там видно фреймы дольше 16.6 мс. Кликаете → видите callstack.
- Если CPU чист — Rendering & GPU Usage — кадры могут “застревать” на vsync waiting GPU.
Profiler Markers — свои метки
using Unity.Profiling;
public class EnemyManager : MonoBehaviour
{
static readonly ProfilerMarker s_UpdateAllMarker = new("EnemyManager.UpdateAll");
private void Update() {
using (s_UpdateAllMarker.Auto()) {
// ваш hot-path code
}
}
}
Маркер появится в Profiler как именованная секция. Незаменимо для понимания “что съело время” внутри своего кода.
Memory Profiler — глубокий аудит памяти
Отдельный пакет (Memory Profiler). Делает снапшоты памяти и сравнивает между ними. Помогает найти:
- Утечки текстур (например, материал, склонированный через
renderer.materialи не освобождённый). - Загруженные сцены, не выгруженные из памяти.
- Asset bundles, которые остались висеть.
Размер билда
Главные источники веса:
- Текстуры — самое большое. Compress (ASTC для Android, BC для PC). Не кладите 4K-текстуры на объект, который занимает 50 пикселей на экране.
- Аудио — длинные wav-треки. Streaming + Vorbis вместо raw PCM.
- Меши — у моделей с миллионом вершин. Decimate в Blender, или используйте LOD-группы.
- Скрипты и зависимости — обычно мало, но кривая компиляция .NET-библиотек может удивлять.
После сборки Unity пишет Build Report в Editor.log (~/Library/Logs/Unity/Editor.log на
macOS, %LOCALAPPDATA%\Unity\Editor\Editor.log на Windows) с разбивкой “что сколько весит”.
Удобнее смотреть через сторонний инструмент Build Report Inspector или через сами файлы билда
(.unity3d, ассет-бандлы) — но Editor.log даёт минимально работоспособный обзор.
LOD (Level Of Detail)
LOD Group — компонент, в котором у одного объекта несколько уровней детализации (LOD0 — high, LOD1 — middle, LOD2 — low, Culled — невидимо). Камера выбирает уровень по экранному размеру объекта. Бесплатные FPS, особенно в больших открытых сценах.
Окклюзия и culling
- Frustum Culling — объекты вне поля зрения не рендерятся. Включено всегда.
- Occlusion Culling — объекты, скрытые за другими (стенами), не рендерятся. Нужно запекать
(
Window → Rendering → Occlusion Culling), требуетOccluder Static/Occludee Staticфлаги. - Layer Culling Distance — на Camera можно задать, что объекты определённого слоя рендерятся только до X метров (травинки исчезают на 30м, деревья — на 200м).
WebGL / WebGPU
Если цель — браузер:
- Только IL2CPP, только AOT.
- Нет потоков по умолчанию (есть Threads experimental с COOP/COEP-заголовками на хостинге).
- Большой initial download (десятки мегабайт). Используйте Brotli compression.
- Audio с ограничениями (AudioContext autoplay policies).
- WebGPU backend — публично доступен с Unity 6.1 (март 2025). На май 2026 поддерживается всеми основными браузерами (Chrome, Firefox с июля 2025, Safari 26 с сентября 2025). Даёт compute shaders, лучшую производительность, поддерживает Forward+. Важно: в Unity Manual 6.x WebGPU всё ещё помечен как experimental, не для production. Для прототипов и dev-сборок — отличный выбор; для shipping — оценивайте риски и оставляйте WebGL2-fallback.
Чек-лист релиза
- Профайлер показывает стабильные 60 FPS на target-устройстве в репрезентативной сцене.
- GC Alloc в
Update≈ 0 в нормальном gameplay. - Draw calls < разумного предела для платформы (мобайл — < 200, PC — < 1000 при средней сцене).
- Текстуры сжаты, не сырая PNG/TGA в импорте.
- LOD на тяжёлых моделях.
- Occlusion culling запечена для интерьеров.
- Player Settings: версия игры, иконка, splash, certificates (для подписи).
- Билд протестирован на целевом устройстве, не только на dev-машине.
- Logging выключен в release (через
#if DEBUGили Log Strip Level).
В следующем (заключительном) разделе — короткий глоссарий: термины Unity и их веб-аналоги.