版本:Unity 6 (6000.0)
语言:英语
原生插件
为桌面平台构建插件

分析底层原生插件

您可以使用底层原生 插件在 Unity 之外创建的一组代码,用于在 Unity 中创建功能。在 Unity 中可以使用两种类型的插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和原生插件(平台特定的原生代码库)。 更多信息
查看 词汇表
分析器一个窗口,帮助您优化游戏。它显示了在游戏的各个领域花费了多少时间。例如,它可以报告渲染、动画或游戏逻辑中花费的时间百分比。 更多信息
查看 词汇表
API 来扩展 分析器 并收集 原生插件在 Unity 之外创建的平台特定原生代码库,供 Unity 使用。允许您访问 OS 调用和第三方代码库等功能,否则这些功能将无法在 Unity 中使用。 更多信息
查看 词汇表
代码的性能数据,或准备分析数据以发送到第三方分析工具,例如 RazorPlayStation® 硬件中使用的 CPU/GPU 芯片组。 更多信息
查看 词汇表
(PS4)、PIX (Xbox、Windows)、Chrome Tracing、ETW、ITT、Vtune 或 Telemetry。

底层原生插件分析器 API 为 Unity 分析器和外部工具之间的通信提供以下接口

  • IUnityProfiler:使用此接口从 C/C++ 原生插件代码向 Unity 分析器添加检测事件。
  • IUnityProfilerCallbacks:使用此接口拦截 Unity 分析器事件并将它们存储或重定向到其他工具。

IUnityProfiler API 参考

使用 IUnityProfiler 插件 API 向原生插件的 C/C++ 代码添加检测。

插件 API 由 IUnityProfiler 接口表示,该接口在 IUnityProfiler.h 头文件中声明。Unity 将头文件存储在 Unity 安装的 <UnityInstallPath>\Editor\Data\PluginAPI 文件夹中。(在 macOS 上,右键单击 Unity 应用程序,然后选择**显示包内容**。头文件位于 Contents\PluginAPI 中)。

方法 描述
CreateMarker 创建 分析器标记放置在代码中以描述 CPU 或 GPU 事件,然后在 Unity 分析器窗口中显示。默认情况下添加到 Unity 代码,或者您可以使用 ProfilerMarker API 添加您自己的自定义标记。 更多信息
查看 词汇表
,它代表一个命名的检测范围,您可以使用它来生成检测样本。
SetMarkerMetadataName 指定自定义参数名称,这些名称可以与分析器标记的检测样本一起传递。
BeginSample 开始以分析器标记命名的代码的检测部分。
EndSample 结束检测部分。
EmitEvent 发出具有元数据的通用事件。
IsEnabled 如果分析器正在捕获数据,则返回 1。
IsAvailable 对于分析器可用的编辑器或开发版玩家,返回 1,对于发布版玩家,返回 0。
RegisterThread 在指定名称下注册当前线程。
UnregisterThread 从分析器中注销当前线程。

IUnityProfiler 示例

以下示例生成分析器窗口可以显示的分析器事件

#include <IUnityInterface.h>
#include <IUnityProfiler.h>

static IUnityProfiler* s_UnityProfiler = NULL;
static const UnityProfilerMarkerDesc* s_MyPluginMarker = NULL;
static bool s_IsDevelopmentBuild = false;

static void MyPluginWorkMethod()
{
    if (s_IsDevelopmentBuild)
        s_UnityProfiler->BeginSample(s_MyPluginMarker);

    // Code I want to see in Unity Profiler as "MyPluginMethod".
    // ...

    if (s_IsDevelopmentBuild)
        s_UnityProfiler->EndSample(s_MyPluginMarker);
}

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    s_UnityProfiler = unityInterfaces->Get<IUnityProfiler>();
    if (s_UnityProfiler == NULL)
        return;
    s_IsDevelopmentBuild = s_UnityProfiler->IsAvailable() != 0;
    s_UnityProfiler->CreateMarker(&s_MyPluginMarker, "MyPluginMethod", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
}

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
    s_UnityProfiler  = NULL;
}

IUnityProfilerCallbacks API 回调

原生分析器插件 API 在 Unity 的子系统和第三方分析 API 之间提供一个接口,因此您可以使用外部分析工具来分析 Unity 应用程序。IUnityProfilerCallbacks 头文件公开 API,Unity 将其存储在 Unity 安装的 <UnityInstallPath>\Editor\Data\PluginAPI 文件夹中。(在 macOS 上,右键单击 Unity 应用程序,然后选择**显示包内容**。头文件位于 Contents\PluginAPI 中)。

以下 Unity 分析器功能有助于捕获检测数据,以便您可以分析应用程序的性能

分析器功能 描述
类别 Unity 将分析数据分组到类别(例如渲染、脚本和动画)中,并为每个类别分配一种颜色。彩色编码的类别有助于您在分析器窗口中直观地区分数据类型。分析器原生插件 API 获取这些颜色,以便您可以在外部分析工具中使用它们。
使用标志 使用标志充当过滤器,减少 Unity 发送到外部分析工具的数据量。您可以使用使用标志从分析数据中删除不必要的信息,然后再由 Unity 将其发送到外部工具。分析器将以下使用标志应用于事件标记,以便您可以过滤数据

可用性标志 指示标记在 Unity 编辑器、开发版玩家或发布版玩家中是否可用。

详细程度级别 与您在编辑器中执行的任务类型以及该任务所需的详细信息级别(例如内部、调试或用户级别)有关。
帧事件 您可以使用分析器原生插件 API 在外部分析工具中执行帧时间分析。
线程分析 Unity 在线程(例如主线程、渲染线程和作业系统工作线程)上执行大量工作。您可以使用分析器原生插件 API 来启用任何线程上的分析。

要在外部分析器中使用 Unity 分析器生成的检测数据,您可以使用这些最小回调集在集成第三方分析器的 C/C++ 插件代码中使用这些回调集

回调 函数
RegisterCreateCategoryCallback 注册 IUnityProfilerCreateCategoryCallback 回调,以便在 Unity 创建类别时获取 分析器类别标识 Unity 子系统的负载数据(例如,渲染、脚本和动画类别)。Unity 对类别应用颜色编码,以便在 **分析器** 窗口中直观地区分数据类型。
查看 词汇表
名称和颜色。
RegisterCreateMarkerCallback 注册 IUnityProfilerCreateMarkerCallback 回调,该回调在 Unity 创建标记时调用。使用它获取标记的名称、分析器类别和使用标志。回调函数的 const UnityProfilerMarkerDesc* markerDesc 参数表示对标记描述的持久指针,您可以使用它在 RegisterMarkerEventCallback 中过滤标记。
RegisterMarkerEventCallback 注册 IUnityProfilerMarkerEventCallback 回调,Unity 在发生单次、范围、内存分配或垃圾回收事件时调用该回调。然后,您可以使用此回调在外部分析工具中调用相关函数。注意:Unity 使用 GC.Alloc 标记表示内存分配事件,使用 GC.Collect 标记表示垃圾回收事件。
RegisterFrameCallback 将样本封装到逻辑帧中,以便不使用帧的外部分析工具可以使用这些样本。此外,还注册一个回调,Unity 分析器在 Unity 启动下一个逻辑 CPU 帧时运行该回调。
RegisterCreateThreadCallback 注册回调,以便在 Unity 注册线程以进行分析时获取内部线程名称。

IUnityProfilerCallbacks 示例

此示例向您展示如何将 Unity 分析器事件传递到另一个具有 push/pop 语义的分析器。它提供两个函数

  • void MyProfilerPushMarker(const char* name):推送命名标记。
  • void MyProfilerPopMarker():弹出检测标记。

以下示例提供了将开始和结束检测事件从 Unity 分析器传递到外部分析器所需的最小实现

#include <IUnityInterface.h>
#include <IUnityProfilerCallbacks.h>

static IUnityProfilerCallbacks* s_UnityProfilerCallbacks = NULL;

static void UNITY_INTERFACE_API MyProfilerEventCallback(const UnityProfilerMarkerDesc* markerDesc, UnityProfilerMarkerEventType eventType, unsigned short eventDataCount, const UnityProfilerMarkerData* eventData, void* userData)
{
    switch (eventType)
    {
        case kUnityProfilerMarkerEventTypeBegin:
        {
            MyProfilerPushMarker(markerDesc->name);
            break;
        }
        case kUnityProfilerMarkerEventTypeEnd:
        {
            MyProfilerPopMarker();
            break;
        }
    }
}

static void UNITY_INTERFACE_API MyProfilerCreateMarkerCallback(const UnityProfilerMarkerDesc* markerDesc, void* userData)
{
    s_UnityProfilerCallbacks->RegisterMarkerEventCallback(markerDesc, MyProfilerEventCallback, NULL);
}

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    s_UnityProfilerCallbacks = unityInterfaces->Get<IUnityProfilerCallbacks>();
    s_UnityProfilerCallbacks->RegisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
}

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
    s_UnityProfilerCallbacks->UnregisterCreateMarkerCallback(&MyProfilerCreateMarkerCallback, NULL);
    s_UnityProfilerCallbacks->UnregisterMarkerEventCallback(NULL, &MyProfilerEventCallback, NULL);
}

注意:要从所有标记中注销给定的回调,请运行 UnregisterEventCallback,并将第一个参数设置为 null

UnitySystracePlugin 示例

您可以动态注册和注销标记回调,每帧一次。以下示例通过启用和禁用回调来最大程度地减少分析开销,具体取决于第三方分析状态。

| static void UNITY_INTERFACE_API SystraceFrameCallback(void* userData)
{
    bool isCapturing = ATrace_isEnabled();
    if (isCapturing != s_isCapturing)
    {
        s_isCapturing = isCapturing;
        if (isCapturing)
        {
            s_UnityProfilerCallbacks->
              RegisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
        }
        else
        {
            s_UnityProfilerCallbacks->
              UnregisterCreateMarkerCallback(SystraceCreateEventCallback, NULL);
            s_UnityProfilerCallbacks->
              UnregisterMarkerEventCallback(NULL, SystraceEventCallback, NULL);
        }
    }
}

注意:要从所有标记中注销给定的回调,请运行 UnregisterEventCallback,并将第一个参数设置为 null

特殊标记

Unity 具有以下包含有用元数据的特殊标记

  • Profiler.DefaultMarker
  • GC.Alloc

Profiler.DefaultMarker

Profiler.DefaultMarker 是 Unity 为 Profiler.BeginSampleProfiler.EndSample 事件保留的标记。

在前面的示例中,kUnityProfilerMarkerEventTypeBegin eventType 对应于 Profiler.BeginSample 事件,并具有以下数据

  • Int32:UnityEngine.Object 实例 ID。如果未指定对象,则为 0。
  • UInt16 数组:传递给 Profiler.BeginSample 的 UTF16 字符串。大小以字节为单位。
  • UInt32:类别索引。

GC.Alloc

GC.Alloc 是对应于垃圾回收分配的标记。它具有以下数据

  • Int64:分配的大小。

其他资源

原生插件
为桌面平台构建插件