
Это одна из нескольких страниц, предоставляющих подробные рекомендации по оптимизации ваших игр для ПК и консолей. Вы можете найти полную коллекцию в бесплатной электронной книге, Оптимизируйте производительность вашей консоли и ПК-игры, заполненной более чем 80 практическими советами и лучшими практиками для оптимизации производительности.
Проблема: Когда один элемент изменяется на канвасе интерфейса, это загрязняет весь канвас.
Канвас — это базовый компонент Unity UI. Он генерирует объекты, которые представляют элементы интерфейса, размещенные на нем, регенерирует объекты, когда элементы интерфейса изменяются, и создает вызовы отрисовки к графическому процессору, чтобы интерфейс действительно отображался.
Генерация этих объектов может быть дорогой. Элементы интерфейса необходимо собирать в пакеты, чтобы они отрисовывались с минимальным количеством вызовов отрисовки. Поскольку генерация пакетов является дорогой, мы хотим регенерировать их только при необходимости. Проблема в том, что, когда один или несколько элементов изменяются на холсте, весь холст должен быть проанализирован снова, чтобы выяснить, как оптимально отрисовать его элементы.
Многие пользователи строят весь интерфейс своей игры на одном холсте с тысячами элементов. Когда они изменяют один элемент, они могут испытывать всплеск загрузки ЦП, который длится несколько миллисекунд. Чтобы узнать больше о том, почему перестройка так дорога, перейдите к отметке 24:55 в этой сессии Unite.
Решение: Разделите свои холсты.
Каждый холст — это остров, который изолирует свои элементы от элементов других холстов. Воспользуйтесь способностью UGUI поддерживать несколько холстов, разделив свои холсты, чтобы решить проблемы с пакетированием в Unity UI.
Вы также можете вложить холсты, что позволяет дизайнерам создавать большие иерархические интерфейсы, не задумываясь о том, где находятся разные элементы на экране между холстами. Дочерние холсты также изолируют содержимое как от своего родителя, так и от соседних холстов. Они поддерживают свою собственную геометрию и выполняют собственное пакетирование. Один из способов решить, как их разделить, основан на том, как часто их нужно обновлять. Держите статические элементы интерфейса на отдельном холсте, а динамические элементы, которые обновляются одновременно, на меньших подхолстах. Также убедитесь, что все элементы интерфейса на каждом холсте имеют одинаковое значение Z, материалы и текстуры.

Проблема: Недостаточное использование Graphic Raycaster
Graphic Raycaster — это компонент, который переводит ваш ввод в события интерфейса. Более конкретно, он переводит клики по экрану или касания на экране в события интерфейса, а затем отправляет их заинтересованным элементам интерфейса. Вам нужен Graphic Raycaster на каждом холсте, который требует ввода, включая подхолсты. Однако он также проходит через каждую точку ввода на экране и проверяет, находятся ли они в RectTransform интерфейса, что может привести к потенциальным накладным расходам.
Несмотря на свое название, Graphic Raycaster на самом деле не является лучевым кастером. По умолчанию он только тестирует графику пользовательского интерфейса. Он берет набор элементов пользовательского интерфейса, которые заинтересованы в получении ввода на данном холсте, и выполняет проверки пересечения. Например, он проверяет, отмечена ли точка, в которой происходит событие ввода, относительно RectTransform каждого элемента пользовательского интерфейса на холсте Graphic Raycaster как интерактивная.
Проблема в том, что не все элементы пользовательского интерфейса заинтересованы в получении обновлений.
Решение: Удалите Graphic Raycasters из неинтерактивных холстов пользовательского интерфейса и отключите Raycast Target для статических или неинтерактивных элементов.
В частности, текст на кнопке, отключающий Raycast Target, напрямую уменьшит количество проверок пересечения, которые Graphic Raycaster должен выполнять в каждом кадре.
Проблема: Иногда Graphic Raycaster действительно действует как лучевой кастер.
Если вы установите режим рендеринга на вашем холсте в Worldspace Camera или Screen Space Camera, вы можете добавить блокирующую маску. Блокирующая маска определяет, будет ли Raycaster посылать лучи через 2D или 3D физику, чтобы определить, блокирует ли какой-либо физический объект возможность пользователя взаимодействовать с пользовательским интерфейсом.
Решение: Посылка лучей через 2D или 3D физику может быть затратной, поэтому используйте эту функцию экономно.
Минимизируйте количество Graphic Raycasters, исключив их из неинтерактивных холстов пользовательского интерфейса, так как в этом случае нет необходимости проверять события взаимодействия.
Узнайте больше о Graphic Raycaster в этой документации.

Проблема: Большие списки, представления сетки и многочисленные наложенные элементы пользовательского интерфейса затратны.
Большие списки и представления сетки дороги, а наложение многочисленных элементов пользовательского интерфейса (т.е. карты, сложенные в игре с картами) создает перерасход.
Решение: Избегайте многочисленных наложенных элементов пользовательского интерфейса.
Настройте свой код, чтобы объединить наложенные элементы пользовательского интерфейса во время выполнения в меньшее количество элементов и партий.
Если вам нужно создать большой список или представление сетки, например, экран инвентаря с сотнями предметов, рассмотрите возможность повторного использования меньшего пула элементов пользовательского интерфейса, а не одного элемента пользовательского интерфейса для каждого предмета.
Посмотрите этот проект GitHub для примера оптимизированного списка прокрутки.

Проблема: Каждый элемент пользовательского интерфейса, который пытается испортить свою компоновку, выполнит как минимум один вызов GetComponent.
Когда один или несколько дочерних UI-элементов изменяются в системе компоновки, компоновка становится "грязной". Измененные дочерние элементы аннулируют систему компоновки, которая их содержит.
Система компоновки — это набор смежных групп компоновки, непосредственно над элементом компоновки. Элемент компоновки — это не только компонент элемента компоновки (UI-изображения, тексты и Scroll Rects), он также включает в себя элементы компоновки — так же, как Scroll Rects также являются группами компоновки.
Теперь, что касается проблемы: Каждый UI-элемент, который помечает свою компоновку как "грязную", выполнит, по крайней мере, один вызов GetComponent. Этот вызов ищет действительную группу компоновки у родителя элемента компоновки. Если он находит одну, он продолжает подниматься по иерархии Transform, пока не прекратит поиск групп компоновки или не достигнет корня иерархии; что бы ни произошло первым. Таким образом, каждая группа компоновки добавляет один вызов GetComponent к процессу загрязнения каждого дочернего элемента компоновки, что делает вложенные группы компоновки крайне плохими для производительности.
Решение: Избегайте групп компоновки, когда это возможно.
Используйте якоря для пропорциональных компоновок. На горячих UI с динамическим количеством UI-элементов рассмотрите возможность написания собственного кода для расчета компоновок. Убедитесь, что вы используете это по мере необходимости, а не для каждого отдельного изменения.
Узнайте больше о группах компоновки в нашей документации.

Проблема: Неправильное использование пула UI-объектов
Люди часто используют пул UI-объектов, изменяя родительские элементы и затем отключая их, что вызывает ненужное загрязнение.
Решение: Сначала отключите объект, затем измените его родительский элемент в пуле.
Вы загрязните старую иерархию один раз, но как только вы измените его родительский элемент, вы избежите загрязнения старой иерархии во второй раз — и вы не загрязните новую иерархию вообще. Если вы удаляете объект из пула, сначала измените его родительский элемент, обновите свои данные, а затем включите его.
Узнайте больше о концепциях базового пуллинга объектов в Unity.

Проблема: Не знаю, как скрыть Canvas
Иногда полезно скрывать элементы UI и Canvases. Но как это сделать эффективно?
Решение: Отключите сам компонент Canvas.
Отключение компонента Canvas остановит его от выдачи вызовов отрисовки на GPU. Таким образом, Canvas больше не будет виден. Однако Canvas не сбросит свой буфер вершин, он сохранит все свои меши и вершины. Когда вы снова включите его, он не вызовет перестройку – он просто начнет снова их рисовать.
Кроме того, отключение компонента Canvas не вызывает дорогие обратные вызовы OnDisable/OnEnable через иерархию Canvas. Просто будьте осторожны, отключая дочерние компоненты, которые выполняют дорогой код на каждом кадре.
Узнайте больше о компоненте Canvas здесь.
Проблема: Использование аниматоров в вашем UI
Аниматоры будут изменять свои элементы UI на каждом кадре, даже если значение в анимации не меняется.
Решение: Используйте код для анимации UI.
Ставьте аниматоры только на динамические элементы UI, которые всегда меняются. Для элементов, которые редко меняются или которые меняются временно в ответ на события, напишите свой собственный код или используйте систему tweening. Существует множество отличных решений для этого, доступных в Asset Store.
Проблема: Плохая производительность с полноэкранным UI
Если ваша игра отображает экран паузы или начала, который полностью закрывает сцену, остальная часть игры все еще рендерится на заднем плане, что может повлиять на производительность.
Решение: Скрыть все остальное.
Если у вас есть экран, который закрывает все остальное в сцене, отключите камеру, отображающую 3D-сцену. Аналогично, отключите элементы Canvas, скрытые за верхним Canvas.
Рассмотрите возможность снижения Application.targetFrameRate во время полноэкранного UI, так как вам не нужно обновлять его на 60 fps.
Оптимизируйте производительность игр для консолей и ПК
Вебинар «Ускорьте успех»: Преображение Unity UI
Продолжение вебинара «Ускорьте успех»: Вопросы и ответы по преображению Unity UI
Как оптимизировать производительность игры с использованием камеры – Часть I
Поддержка, услуги, экономия: Посмотрите свои преимущества Unity Pro

Предоставьте своим игрокам лучший игровой опыт. С более чем 80 практическими советами и лучшими практиками от экспертов Unity вы можете оптимизировать свои игры для ПК и консолей.
Созданные командами успеха Unity и Unity Studio Productions, эти подробные практики – собранные из реальных взаимодействий с ведущими студиями – помогут улучшить общую производительность вашей игры.