Визуализация счетчиков профилирования
После того, как вы добавили счетчики Profiler в свой код, вы можете визуализировать их в окне Profiler или в сборке вашего приложения.
Визуализация пользовательских счетчиков в окне Profiler
Для просмотра данных, генерируемых ProfilerCounter или ProfilerCounterValue в окне Profiler, можно использовать пользовательский модуль Profiler. Это может помочь визуально распознать связи с другими системными показателями и быстро выявить проблемы производительности.
Добавление показателей в код
В следующем примере предполагается, что класс GameManager отвечает за высокоуровневую логику и знает о противниках. Чтобы обновить значение счётчика, в Update или LateUpdate методом (в зависимости от того, когда логика выполняется со спарением или уничтожением врагов), используйте Sample метод, чтобы подтолкнуть значение счета врага до Profiler:
using UnityEngine;
using Unity.Profiling;
class GameManager : MonoBehaviour
{
Enemy[] m_Enemies;
void Update()
{
GameStats.EnemyCount.Sample(m_Enemies.Length);
}
}
Чтобы передать количество пуль в Profiler, в этом примере предполагается, что существует shell-скрипт, который управляет жизненным циклом пули. Затем он увеличивает значение GameStats.BulletCount в Awake и уменьшает его в OnDestroy, чтобы дать точную информацию о текущем потоке пуль в игре.
using UnityEngine;
using Unity.Profiling;
public class Shell : MonoBehaviour
{
void Awake()
{
GameStats.BulletCount.Value += 1;
}
void OnDestroy()
{
GameStats.BulletCount.Value -= 1;
}
}
Примечание: Unity компилирует и ProfilerCounter и ProfilerCounterValue в неразработочных сборках.
Добавление модуля в окно Profiler
Используйте редактор модулей Profiler для выбора встроенных или вновь добавленных счетчиков для визуализации. Чтобы открыть редактор модулей Profiler:
- Откройте окно Profiler (Window > Analysis > Profiler).
- Выберите раскрывающееся меню Profiler Module в верхнем левом углу окна. Нажмите на значок шестерни, и редактор модуля Profiler откроется в новом окне.
- Выберите Добавить и затем выберите счетчики, которые вы хотите визуализировать из списка Пользователя в правой части окна.
Важно: Если вы не загрузили никаких данных в окно Profiler, то любые созданные вами счетчики не появляются в панели Доступные счетчики при загрузке Редактора Модулей Profiler. Чтобы просмотреть пользовательские счетчики, захватывает или загружает некоторые данные, которые содержат ваши выделенные счетчики вместе с Profiler, и заново открывает Редактор Модулей Profiler.
Затем вы можете просмотреть данные в окне Profiler наряду с другими счетчиками. Дополнительные сведения см. в Создание пользовательских модулей Profiler.
Примечание: Счётчики, объявленные как статические, инициализируются динамически в коде C# при инициализации типа и могут быть недоступны, пока действительно не будут инициализированы и использованы. Это относится и к режиму Edit, и к режиму Play. Если ваши счётчики не появляются в Profiler Module Editor, записать некоторые данные с Profiler сначала на несколько кадров.
Визуализация счетчиков Profiler во встроенном плеере
При запуске проекта в встроенном проигрывателе у вас нет доступа к окну Profiler. Однако вы можете отображать счетчики как элементы UI в встроенном проигрывателе. Это означает, что вы можете включить инструменты профилирования в сборку вашего приложения.
На следующем изображении показаны счетчики в верхнем левом углу сцены с использованием пользовательского UI в встроенном проигрывателе:
Примечание: Не все счетчики Profiler доступны в Release Players (компилациях, не относящихся к разработке). Используйте ProfilerRecorder.Valid, чтобы определить, доступны ли данные и может ли Profiler записывать их. В качестве альтернативы вы можете использовать ProfilerRecorderHandle.GetAvailable для перечисления всех доступных статистических данных Profiler.
Получение значений счетчиков у игроков
Счетчики Profiler дают вам представление о важных показателях системы игры или движка. Если у вас есть настройка непрерывной интеграции или вы хотите визуализировать ключевые показатели производительности в вашем приложении во время тестовой игры, вы можете использовать ProfilerRecorder API для получения пользовательских и встроенных значений счетчиков Profiler.
Например, в следующем сценарии отображается время кадра, размер кучи Mono/IL2CPP и общая память, используемая приложением.
using System.Collections.Generic;
using System.Text;
using Unity.Profiling;
using UnityEngine;
public class StatsScript : MonoBehaviour
{
string statsText;
ProfilerRecorder systemMemoryRecorder;
ProfilerRecorder gcMemoryRecorder;
ProfilerRecorder mainThreadTimeRecorder;
double GetRecorderFrameAverage(ProfilerRecorder recorder)
{
var samplesCount = recorder.Capacity;
if (samplesCount == 0)
return 0;
double r = 0;
unsafe
{
var samples = stackalloc ProfilerRecorderSample[samplesCount];
recorder.CopyTo(samples, samplesCount);
for (var i = 0; i < samplesCount; ++i)
r += samples[i].Value;
r /= samplesCount;
}
return r;
}
void OnEnable()
{
systemMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "System Used Memory");
gcMemoryRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "GC Reserved Memory");
mainThreadTimeRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Internal, "Main Thread", 15);
}
void OnDisable()
{
systemMemoryRecorder.Dispose();
gcMemoryRecorder.Dispose();
mainThreadTimeRecorder.Dispose();
}
void Update()
{
var sb = new StringBuilder(500);
sb.AppendLine($"Frame Time: {GetRecorderFrameAverage(mainThreadTimeRecorder) * (1e-6f):F1} ms");
sb.AppendLine($"GC Memory: {gcMemoryRecorder.LastValue / (1024 * 1024)} MB");
sb.AppendLine($"System Memory: {systemMemoryRecorder.LastValue / (1024 * 1024)} MB");
statsText = sb.ToString();
}
void OnGUI()
{
GUI.TextArea(new Rect(10, 30, 250, 50), statsText);
}
}
Важно: Использование ProfilerRecorder.Dispose ресурсов, связанных с осуществлением ProfilerRecorder.
Получение значений счетчиков из данных кадра Profiler в Редакторе
Чтобы получить значения счетчика Profiler при обработке данных кадра Profiler в Редакторе, используйте FrameDataView API.
Вы можете использовать FrameDataView.GetCounterValueAsInt, FrameDataView.GetCounterValueAsLong, FrameDataView.GetCounterValueAsFloat и FrameDataView.GetCounterValueAsDouble для получения значения кадра конкретного счетчика, например:
using UnityEditor.Profiling;
class Example
{
static int ExtractMyCounterValue(FrameDataView frameData, string counterName)
{
var counterMarkerId = frameData.GetMarkerId(counterName);
return frameData.GetCounterValueAsInt(counterMarkerId);
}
}