Unity 6.3
0 онлайн 96 гостей 3 в системе
Вход
Оптимизация Шаг 48 из 208

Анализ следов Profiler

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

Расшифровка следов запуска

При просмотре трассировки времени запуска, есть два ключевых метода для проверки: UnityInitApplicationGraphics и UnityLoadApplication. Эти два метода являются основными местами, где конфигурация, ассеты и код проекта могут повлиять на время запуска.

Примечание: Время запуска вашего приложения различается от платформы к платформе. На большинстве платформ, запуск происходит в то время как запуск экрана появляется.

Трассировка инструментов примера проекта Unity, работающего на устройстве iOS
Трассировка инструментов примера проекта Unity, работающего на устройстве iOS

На приведенном выше скриншоте из трека Instruments примера проекта Unity, запущенного на устройстве iOS, в методе startUnity для конкретной платформы обратите внимание на методы UnityInitApplicationGraphics и UnityLoadApplication.

UnityInitApplicationGraphics выполняет много внутренней работы: настраивает графическое устройство и инициализирует множество внутренних систем Unity. Он также инициализирует Система ресурсов путем загрузки индекса всех файлов, содержащихся в системе ресурсов.

Unity Система ресурсов включает все файл актива в своих данных, что в Resources папка в Assets папку проекта. Это включает любые файлы в папке Resources Таким образом, время, требуемое для инициализации системы ресурсов увеличивается в зависимости от количества файлов в папке. Resources папки в проекте приложения.

UnityLoadApplication содержит методы, которые загружают и инициализируют первый Scene в проекте. Это включает в себя десерриализацию и инстанционирование данных, необходимых для отображения первого Scene, таких как компиляция Shaders, загрузка Textures и инстанционирование GameObjects. Также Unity выполняет обратные вызова Awake всех MonoBehaviourв первом Scene.

Эти процессы означают, что если в обратном вызове Awake в первом Scene проекта имеется какой-либо длительно работающий код, то этот код может быть ответственным за замедление первоначального времени запуска проекта. Решение этой проблемы включает либо устранение медленного кода, либо выполнение его в другом месте жизненного цикла приложения.

Расшифровка трасс времени выполнения

Для профилирования следов, запечатленных после первоначального времени запуска, основным местом интереса является метод PlayerLoop. Это главный цикл Unity, и код в нем выполняется один раз в кадре.

Приборы для отслеживания примера проекта Unity
Приборы для отслеживания примера проекта Unity

Вышеприведенный скриншот иллюстрирует некоторые из наиболее влияющих на производительность методов в PlayerLoop. Примечание: Названия методов в PlayerLoop могут различаться между версиями Unity.

PlayerRender — это метод, который запускает систему рендеринга Unity. Это включает в себя удаление объектов, вычисление динамических пакетов и отправку инструкций рисования в GPU.. Любые эффекты изображений или обратные вызова скриптов на основе рендеринга (например,,OnWillRenderObject,) также запускаются здесь. В целом, это должно быть главным потребителем времени CPU, когда проект интерактивен.

BaseBehaviourManager вызывает три шаблонные версии CommonUpdate. Они вызывают определенные обратные вызова внутри MonoBehaviour, присоединенных к активному GameObjects в текущем Scene:

  • CommonUpdate<UpdateManager> вызовы Update обратные вызова
  • CommonUpdate<LateUpdateManager> вызовы LateUpdate обратные вызова
  • CommonUpdate<FixedUpdateManager> вызывает FixedUpdate, если система физики открылась

В целом, BaseBehaviourManager::CommonUpdate<UpdateManager> является наиболее полезным семейством методов для проверки, потому что оно является точкой входа для большинства скриптовых кодов, запущенных в проекте Unity.

Существует несколько других методов, которые полезны для проверки:

  • UI::CanvasManager вызывает несколько различных обратных вызовов, если проект использует систему UGUI. Это включает пакетные вычисления Unity UI и обновления макета; две операции, которые чаще всего вызывают появление CanvasManager в Profiler.
  • DelayedCallManager::Update запускает сопроцедуры.
  • PhysicsManager::FixedUpdate запускает физическую систему PhysX. В основном это работа внутреннего кода PhysX. Количество физических объектов в текущей сцене — например, Rigidbody и Collider влияют на внутренний код PhysX. Сюда же попадают обратные вызовы, связанные с физикой, в частности OnTriggerStay и OnCollisionStay.

Если проект использует физику 2D, то она появляется как аналогичный набор вызовов под Physics2DManager::FixedUpdate.

Разбор метода скрипта

При вызове скриптов на платформах, кросс-компилированных с IL2CPP, искать строки трассировки, содержащие ScriptingInvocation объект. Это точка, в которой внутренний нативный код Unity переходит в среду выполнения скриптов, чтобы выполнить код скрипта. Примечание: Технически, после того, как Unity запускает ваш код C# через IL2CPP, он также становится нативным кодом. Однако, этот кросс-компилированный код в основном выполняет методы через фреймворк runtime IL2CPP и не похож на написанный от руки C++.

Треки из примера проекта Unity
Треки из примера проекта Unity

На вышеприведённом скриншоте методы, вложенные под строкой RuntimeInvoker_Void, являются частью кросс-компилированных скриптов C#, которые Unity выполняет один раз в кадре.

Имена строк трассировки состоят из имени исходного класса, символа подчёркивания и имени исходного метода. В этом примере трассировки видно EventSystem.Update, PlayerShooting.Update и ряд других Update Это стандартные Unity Update обратные вызовы, найденные в большинстве MonoBehaviours.

Вы можете развернуть эти методы, чтобы увидеть, какие методы в них потребляли CPU времени. Это включает другие методы скриптов в проекте, Unity, APIs и код библиотеки C#.

Вышеприведенный трек показывает, что метод StandaloneInputModule.Process пролегал через весь UI один раз в кадре. Этот метод обнаруживает, были ли какие-либо касательные события, зависшие над элементами UI или активировавшие их. Метод, итерирующий все элементы UI и проверяющий, находится ли позиция мыши в пределах их ограничивающего прямоугольника, ресурсоемкий.

Загрузка ассетов

Вы также можете идентифицировать загрузку ассетов в трассе CPU. Основным методом, указывающим на загрузку ассета, является SerializedFile::ReadObject. Этот метод соединяет поток двоичных данных из файла с системой сериализации Unity, которая работает через метод Transfer. Метод Transfer применяется ко всем типам ассетов, таким как Тексты, MonoBehaviours и Системы Частиц.

Следы погрузки Scene
Следы погрузки Scene

Вышеприведенный скриншот представляет собой след Unity, загружающего Scene. Когда он загружает Scene, Unity читает и десериализует все Assets в Scene, как это обозначено вызовами различных методов Transfer под SerializedFile::ReadObject.

Если во время выполнения наблюдается замедление производительности, а в трассировке производительности показано, что SerializedFile::ReadObject использовал значительное количество времени, это означает, что загрузки ассетов снизили частоту кадров. Примечание: SerializedFile::ReadObject обычно появляются в главном потоке, когда SceneManager, Resources или AssetBundle APIs запрашивают синхронные загрузки ассетов.

Чтобы решить эту проблему, вы можете сделать загрузку ассетов асинхронной (что переместит тяжелый вызов ReadObject в рабочий поток), или предварительно загрузить некоторые тяжелые ассеты.

Вызовы Transfer также появляются, когда Unity клонирует объекты (обозначенные методом CloneObject в треке). Если вызов Transfer появляется под вызовами CloneObject, то Unity не загружает Asset из хранилища. Вместо этого Unity передаёт данные старого объекта новому объекту. Для этого Unity сериализирует старый объект и десериялизирует полученные данные как новый объект.