• Игры
  • Отрасль
  • Ресурсы
  • Сообщество
  • Обучение
  • Поддержка
Услуги разработчиков
Движок Unity
Создавайте 2D и 3D игры для любой платформы
ЗагрузитьТарифы и цены
Монетизация
Встроенная покупка (IAP)
Откройте и управляйте IAP в разных магазинах
Mediation
Максимизируйте доход и оптимизируйте монетизацию
Качество рекламы
Защитите пользовательский опыт вашего приложения
Tapjoy
Создавайте долгосрочную лояльность пользователей
Все продукты монетизации
Привлечение пользователей
Привлечение пользователей
Будьте замечены и привлекайте мобильных пользователей
Unity Vector AI
Соединяйте игроков с подходящими играми
Aura - реклама на устройстве
Достигайте пользователей на устройстве в пиковые моменты вовлеченности
Все продукты для роста
Примеры использования
3D сотрудничество
Создавайте и просматривайте 3D проекты в реальном времени
Иммерсивное обучение
Обучение в иммерсивных средах
Пользовательские опыты
Создавайте интерактивные 3D опыты
Все отраслевые решения
Отрасли
Производство
Достигнуть операционного совершенства
Торговля
Преобразовать опыт в магазине в онлайн-опыт
Автомобильная отрасль
Повысить инновации и опыт в автомобиле
Все отрасли
Техническая библиотека
Документация
Официальные руководства пользователя и ссылки на API
Инструменты для разработчиков
Версии релизов и трекер проблем
План развития
Обзор предстоящих функций
Глоссарий
Библиотека технических терминов
Дополнительная информация
Истории успеха
Истории успеха из реальной жизни
Руководства по лучшим практикам
Советы и хитрости от экспертов
Все ресурсы
Что нового
Блог
Обновления, информация и технические советы
Новости
Новости, истории и пресс-центр
Сообщество
Обсуждения
Обсуждать, решать проблемы и соединяться
События
Глобальные и местные события
Истории сообщества
Made with Unity
Показ Unity-креаторов
Прямые трансляции
Присоединяйтесь к разработчикам, креаторам и инсайдерам
Награды Unity
Празднование Unity-креаторов по всему миру
Для каждого уровня
Unity Learn
Освойте навыки Unity бесплатно
Профессиональное обучение
Повышайте уровень своей команды с тренерами Unity
Не использовали Unity раньше
С чего начать
Приступите к обучению
Основные пути Unity
Не использовали Unity раньше? Начните свое путешествие
Практические руководства
Практические советы и лучшие практики
Образование
Для студентов
Запустите свою карьеру
Для преподавателей
Улучшите свое преподавание
Лицензия Education Grant
Принесите мощь Unity в ваше учебное заведение
Программы сертификации
Докажите свое мастерство в Unity
Варианты поддержки
Получить помощь
Помогаем вам добиться успеха с Unity
Планы успеха
Достигайте своих целей быстрее с помощью экспертов
FAQ
Ответы на часто задаваемые вопросы
Связаться с нами
Свяжитесь с нашей командой
Тарифы и цены
Язык
  • English
  • Deutsch
  • 日本語
  • Français
  • Português
  • 中文
  • Español
  • Русский
  • 한국어
Соцсети
Валюта
Купить
  • Продукты
  • Unity Ads
  • Подписка
  • Unity Asset Store
  • Торговые посредники
Образование
  • Студенты
  • Преподаватели
  • Образовательные учреждения
  • Сертификация
  • Learn
  • Программа развития навыков
Загрузить
  • Unity Hub
  • Архив загрузок
  • Программа бета-тестирования
Unity Labs
  • Лаборатории
  • Публикации
Ресурсы
  • Платформа обучения
  • Сообщество
  • Документация
  • Unity QA
  • FAQ
  • Статус услуг
  • Истории успеха
  • Made with Unity
Unity
  • Наша компания
  • Новостная рассылка
  • Блог
  • События
  • Вакансии
  • Справка
  • Пресса
  • Партнеры
  • Инвесторы
  • Партнеры
  • Безопасность
  • Отдел Social Impact
  • Инклюзия и разнообразие
  • Связаться с нами
© Unity Technologies, 2025
  • Правовая информация
  • Политика конфиденциальности
  • Cookie-файлы
  • Использование персональных данных

Unity, логотипы Unity и другие торговые знаки Unity являются зарегистрированными торговыми знаками компании Unity Technologies или ее партнеров в США и других странах (подробнее здесь). Остальные наименования и бренды являются торговыми знаками соответствующих владельцев.

Hero background image

Расширенное программирование и архитектура кода

Изучите архитектуру вашего кода, чтобы дополнительно оптимизировать рендеринг вашей графики. Это четвертая статья в серии, которая раскрывает советы по оптимизации для ваших проектов Unity. Используйте их в качестве руководства для работы на более высоких частотах кадров с меньшими ресурсами. После того как вы попробуете эти лучшие практики, обязательно ознакомьтесь с другими страницами в серии: Настройка вашего проекта Unity для повышения производительности Оптимизация производительности для графики высокого класса Управление использованием GPU для игр на ПК и консолях Улучшенная физическая производительность для плавного игрового процесса
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.
Нажмите здесь.
  • Понимание Unity PlayerLoop
  • Создание собственного менеджера обновлений
  • Минимизируйте код, который выполняется каждый кадр
  • Кэшируйте результаты затратных функций
  • Избегайте пустых событий Unity и операторов отладки
  • Отключите ведение журнала трассировки стека
  • Используйте хэш-значения вместо строковых параметров
  • Используйте пул объектов
  • Используйте мощь ScriptableObjects

Понимание Unity PlayerLoop

Unity PlayerLoop содержит функции для взаимодействия с ядром игрового движка. Эта структура включает в себя ряд систем, которые обрабатывают инициализацию и обновления на каждом кадре. Все ваши скрипты будут полагаться на этот PlayerLoop для создания игрового процесса. При профилировании вы увидите пользовательский код вашего проекта под PlayerLoop – с компонентами Editor под EditorLoop.

Важно понимать порядок выполнения FrameLoop Unity. Каждый скрипт Unity выполняет несколько функций событий в заранее определенном порядке. Узнайте разницу между Awake, Start, Update и другими функциями, которые создают жизненный цикл скрипта для повышения производительности.

Некоторые примеры включают использование FixedUpdate вместо Update при работе с Rigidbody или использование Awake вместо Start для инициализации переменных или состояния игры до начала игры. Используйте это, чтобы минимизировать код, который выполняется на каждом кадре. Awake вызывается только один раз в течение жизни экземпляра скрипта и всегда перед функциями Start. Это означает, что вы должны использовать Start для работы с объектами, о которых вы знаете, что они могут взаимодействовать с другими объектами или запрашивать их, когда они были инициализированы.

Смотрите диаграмму жизненного цикла скрипта для конкретного порядка выполнения функций событий.

Диаграмма пользовательского менеджера обновлений

Создание собственного менеджера обновлений

Если у вашего проекта есть требовательные к производительности требования (например, игра с открытым миром), рассмотрите возможность создания пользовательского менеджера обновлений с использованием Update, LateUpdate или FixedUpdate.

Распространенный шаблон использования для Update или LateUpdate – это выполнение логики только при выполнении некоторого условия. Это может привести к множеству обратных вызовов на кадр, которые фактически не выполняют никакого кода, кроме проверки этого условия.

Когда Unity вызывает метод сообщения, такой как Update или LateUpdate, он делает вызов межпроцессного взаимодействия – то есть вызов со стороны C/C++ к управляемой стороне C#. Для небольшого количества объектов это не проблема. Когда у вас есть тысячи объектов, эта накладная работа начинает становиться значительной.

Подписывайте активные объекты на этот менеджер обновлений, когда им нужны обратные вызовы, и отписывайте, когда они не нужны. Этот шаблон может сократить множество вызовов межпроцессного взаимодействия к вашим Monobehaviour объектам.

Смотрите техники оптимизации, специфичные для игрового движка для примеров реализации.

Минимизируйте код, который выполняется каждый кадр

Рассмотрите, нужно ли коду выполняться каждый кадр. Вы можете переместить ненужную логику из Update, LateUpdate и FixedUpdate. Эти функции событий Unity являются удобными местами для размещения кода, который должен обновляться каждый кадр, но вы можете извлечь любую логику, которая не нуждается в обновлении с такой частотой.

Выполняйте логику только тогда, когда что-то меняется. Не забудьте использовать такие техники, как паттерн наблюдателя в виде событий, чтобы вызвать конкретную сигнатуру функции.

Если вам нужно использовать Update, вы можете запускать код каждые n кадров. Это один из способов применения Time Slicing, распространенной техники распределения тяжелой нагрузки по нескольким кадрам.

В этом примере мы запускаем ExampleExpensiveFunction один раз каждые три кадра.

Секрет в том, чтобы чередовать это с другой работой, которая выполняется в другие кадры. В этом примере вы можете "запланировать" другие дорогие функции, когда Time.frameCount % interval == 1 или Time.frameCount % interval == 2.

В качестве альтернативы используйте класс пользовательского менеджера обновлений, чтобы обновлять подписанные объекты каждые n кадров.

Кэшируйте результаты затратных функций

В версиях Unity до 2020.2, GameObject.Find, GameObject.GetComponent и Camera.main могут быть дорогими, поэтому лучше избегать их вызова в методах Update.

Кроме того, старайтесь избегать размещения дорогих методов в OnEnable и OnDisable, если они вызываются часто. Частые вызовы этих методов могут способствовать всплескам ЦП.

По возможности запускайте дорогие функции, такие как MonoBehaviour.Awake и MonoBehaviour.Start в фазе инициализации. Кэшируйте необходимые ссылки и повторно используйте их позже. Посмотрите наш предыдущий раздел о Unity PlayerLoop для более подробного выполнения порядка скриптов.

Вот пример, который демонстрирует неэффективное использование повторного вызова GetComponent:

void Update()
{
Renderer myRenderer = GetComponent();
ExampleFunction(myRenderer);
}

Вместо этого вызывайте GetComponent только один раз, так как результат функции кэшируется. Кэшированный результат можно повторно использовать в Update без дополнительных вызовов GetComponent.

Читать больше о Порядке выполнения функций событий.

Избегайте пустых событий Unity и операторов отладки

Логические операторы (особенно в Update, LateUpdate или FixedUpdate) могут замедлять производительность, поэтому отключите свои логические операторы перед созданием сборки. Чтобы сделать это быстро, рассмотрите возможность создания Условного атрибута вместе с директивой предварительной обработки.

Например, вы можете создать пользовательский класс, как показано ниже.

Сгенерируйте ваше лог-сообщение с помощью вашего пользовательского класса. Если вы отключите ENABLE_LOG препроцессор в Настройки игрока > Определить символы скрипта, все ваши логические операторы исчезнут разом.

Обработка строк и текста является распространенной причиной проблем с производительностью в проектах Unity. Вот почему удаление логических операторов и их дорогого форматирования строк может потенциально значительно повысить производительность.

Аналогично, пустые MonoBehaviour требуют ресурсов, поэтому вы должны удалить пустые методы Update или LateUpdate. Используйте директивы препроцессора, если вы используете эти методы для тестирования:

#if UNITY_EDITOR
void Update()
{
}
#endif

Здесь вы можете использовать Update в редакторе для тестирования без ненужных накладных расходов в вашей сборке.

Этот блог-пост о 10,000 вызовах Update объясняет, как Unity выполняет Monobehaviour.Update.

Отключите ведение журнала трассировки стека

Используйте параметры Стек вызовов в Настройки игрока, чтобы контролировать, какие типы лог-сообщений появляются. Если ваше приложение регистрирует ошибки или предупреждающие сообщения в вашей сборке (например, для генерации отчетов о сбоях в дикой природе), отключите Стек вызовов, чтобы улучшить производительность.

Узнайте больше о Логировании стека вызовов.

Используйте хэш-значения вместо строковых параметров

Unity не использует строковые имена для обращения к Animator, Material или Shader свойствам внутри. Для скорости все имена свойств хэшируются в Property IDs, и эти ID используются для обращения к свойствам.

При использовании метода Set или Get на Animator, Material или Shader, используйте метод с целочисленным значением вместо методов со строковым значением. Методы со строковым значением выполняют хэширование строк и затем передают хэшированный ID методам с целочисленным значением.

Используйте Animator.StringToHash для имен свойств Animator и Shader.PropertyToID для имен свойств Material и Shader.

Связано с выбором структуры данных, что влияет на производительность, когда вы итерируете тысячи раз за кадр. Следуйте руководству MSDN по структурам данных в C# в качестве общего руководства для выбора правильной структуры.

Интерфейс скрипта пула объектов

Используйте пул объектов

Instantiate и Destroy могут вызывать всплески сборки мусора (GC). Это обычно медленный процесс, поэтому вместо регулярного создания и уничтожения GameObjects (например, стрельбы пулями из пистолета) используйте пулы предвыделенных объектов, которые можно повторно использовать и перерабатывать.

Создайте повторно используемые экземпляры в определенный момент игры, например, во время экрана меню или экрана загрузки, когда всплеск ЦП менее заметен. Отслеживайте этот "пул" объектов с помощью коллекции. Во время игрового процесса просто включайте следующий доступный экземпляр по мере необходимости и отключайте объекты вместо их уничтожения, прежде чем вернуть их в пул. Это снижает количество управляемых аллокаций в вашем проекте и может предотвратить проблемы с GC.

Аналогично, избегайте добавления компонентов во время выполнения; Вызов AddComponent имеет свои затраты. Unity должен проверять на дубликаты или другие необходимые компоненты каждый раз, когда добавляются компоненты во время выполнения. Создание Prefab с уже настроенными необходимыми компонентами является более производительным, поэтому используйте это в сочетании с вашим Object Pool.

Связано с этим, при перемещении Transforms используйте Transform.SetPositionAndRotation, чтобы обновить как позицию, так и вращение одновременно. Это избегает накладных расходов на изменение Transform дважды.

Если вам нужно создать GameObject во время выполнения, родительский и переместите его для оптимизации, смотрите ниже.

Для получения дополнительной информации о Object.Instantiate смотрите API для скриптов.

Узнайте, как создать простую систему пуллинга объектов в Unity здесь.

Пул объектов Scriptable Object

Используйте мощь ScriptableObjects

Храните неизменяемые значения или настройки в ScriptableObject вместо MonoBehaviour. ScriptableObject - это актив, который существует внутри проекта. Его нужно настроить только один раз, и его нельзя напрямую прикрепить к GameObject.

Создайте поля в ScriptableObject для хранения ваших значений или настроек, затем ссылайтесь на ScriptableObject в ваших MonoBehaviour. Использование полей из ScriptableObject может предотвратить ненужное дублирование данных каждый раз, когда вы создаете объект с этим MonoBehaviour.

Посмотрите этот вводный курс по ScriptableObjects и найдите соответствующую документацию здесь.

ключевое искусство unity 21 11
Получите бесплатную электронную книгу

Одна из наших самых полных руководств когда-либо собирает более 80 практических советов о том, как оптимизировать ваши игры для ПК и консоли. Созданные нашими экспертами в области успеха и Accelerate Solutions, эти углубленные советы помогут вам максимально использовать Unity и повысить производительность вашей игры.

Загрузить электронную книгу