Version: 6000.3
语言: 中文
将探查器计数器添加到代码中
在自己的进程中运行分析器

可视化分析器计数器

探查器计数器添加到代码后,可以在分析器帮助您优化游戏的窗口。它显示了在游戏的各个领域花费了多少时间。例如,它可以报告渲染、动画制作或游戏逻辑所花费的时间百分比。更多信息
请参阅术语表
窗口,或在应用程序的构建中。

在“性能分析器”窗口中可视化自定义计数器

要查看以下数据ProfilerCounterProfilerCounterValue生成,您可以使用自定义的 Profiler 模块。这可能有助于直观地识别与其他系统指标的关系并快速识别性能问题。

向代码添加指标

以下示例假定 GameManager 类处理高级逻辑并了解敌人。要更新计数器的值,请在UpdateLateUpdate方法(取决于何时执行生成或摧毁敌人的逻辑),使用Sample将敌人的计数值推送到 Profiler 的方法:

using UnityEngine;
using Unity.Profiling;

class GameManager : MonoBehaviour
{
    Enemy[] m_Enemies;

    void Update()
    {
        GameStats.EnemyCount.Sample(m_Enemies.Length);
    }
}

为了将项目符号计数传递给分析器,此示例假定有一个管理项目符号生命周期的 shell 脚本。然后它会增加GameStats.BulletCountAwake并减少它OnDestroy提供有关游戏中当前子弹流的准确信息。

using UnityEngine;
using Unity.Profiling;

public class Shell : MonoBehaviour
{
    void Awake()
    {
        GameStats.BulletCount.Value += 1;
    }
    void OnDestroy()
    {
        GameStats.BulletCount.Value -= 1;
    }
}

注意:Unity 编译了ProfilerCounterProfilerCounterValue在非开发版本中。

将自定义模块添加到“探查器”窗口

使用性能分析器模块编辑器为可视化选择内置计数器或新添加的计数器。要打开性能分析器模块编辑器,请执行以下作:

  1. 打开“分析器”窗口(“分析>”窗口>分析器“)。
  2. 选择窗口左上角的 分析器模块(Profiler Module) 下拉菜单。单击齿轮图标,Profiler 模块编辑器将在新窗口中打开。
  3. 选择“添加”,然后从窗口右侧的“用户”列表中选择要可视化的计数器。

重要:如果未将任何数据加载到“性能分析器”窗口中,则加载性能分析器模块编辑器时,创建的任何计数器都不会显示在“可用计数器”窗格中。要查看自定义计数器,请使用性能分析器捕获或加载一些包含发射计数器的数据,然后重新打开性能分析器模块编辑器。

然后,您可以在“探查器”窗口中与其他计数器一起查看数据。有关更多信息,请参阅创建自定义 Profiler 模块

在 Profiler 窗口中具有自定义计数器的模块。
在 Profiler 窗口中具有自定义计数器的模块。

注意:声明为静态的计数器在初始化类型时在 C# 代码中动态初始化,并且在实际初始化和使用它们之前可能不可用。这适用于编辑和播放模式。如果你的计数器未出现在 Profiler 模块编辑器中,请先使用 Profiler 记录一些数据,持续几帧。

在构建的播放器中可视化 Profiler 计数器

在构建的播放器中运行项目时,你无权访问 性能分析器(Profiler) 窗口。但是,你可以在构建的播放器中将计数器显示为 UI 元素。这意味着您可以在应用程序的构建中包含分析工具。

下图显示了场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表
在构建的播放器中使用自定义UI:

叠加自定义信息的坦克游戏
叠加自定义信息的坦克游戏

注意:不是全部Profiler 计数器使用 ProfilerCounter API 放置在代码中,以跟踪指标,例如游戏中生成的敌人数量。更多信息
请参阅术语表
在发布播放器(非开发版本)中可用。用ProfilerRecorder.Valid以确定数据是否可用以及探查器是否可以记录数据。或者,您可以使用ProfilerRecorderHandle.GetAvailable枚举所有可用的探查器统计信息。

获取玩家的计数器值

分析器计数器可让您深入了解重要的游戏或引擎系统指标。如果您有持续集成设置,或者想要在测试期间可视化应用程序中的关键性能指标,您可以使用ProfilerRecorderAPI 来获取自定义和内置的 Profiler 计数器值。

例如,以下脚本显示帧时间 Mono/IL2CPP Unity 开发的脚本后端,在为某些平台构建项目时,可以将其用作 Mono 的替代方案。更多信息
请参阅术语表
堆大小和应用程序使用的总内存。

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应用程序接口。

您可以使用FrameDataView.GetCounterValueAsInt,FrameDataView.GetCounterValueAsLong,FrameDataView.GetCounterValueAsFloatFrameDataView.GetCounterValueAsDouble获取特定计数器的帧值,如下所示:

using UnityEditor.Profiling;

class Example
{
    static int ExtractMyCounterValue(FrameDataView frameData, string counterName)
    {
        var counterMarkerId = frameData.GetMarkerId(counterName);
        return frameData.GetCounterValueAsInt(counterMarkerId);
    }
}

其他资源

将探查器计数器添加到代码中
在自己的进程中运行分析器