包含此页的版本:
不含此页的版本:
您可以使用低级本机插件在 Unity 外部创建的一组代码,用于在 Unity 中创建功能。可以在 Unity 中使用两种插件:托管插件(使用 Visual Studio 等工具创建的托管 .NET 程序集)和本机插件(特定于平台的本机代码库)。详细信息
请参阅术语表 分析器帮助您优化游戏的窗口。它显示了在游戏的各个领域花费了多少时间。例如,它可以报告渲染、动画制作或游戏逻辑所花费的时间百分比。更多信息
请参阅术语表用于扩展探查器并收集本机插件代码的性能数据的 API,或准备分析数据以发送到第三方探查工具,例如 Razor (PS4)、PIX (Xbox、Windows)、Chrome 跟踪、ETW、ITT、Vtune 或遥测。
低级本机插件 Profiler API 提供以下接口,用于 Unity Profiler 和外部工具之间的通信:
使用IUnityProfiler插件 API 以将检测添加到本机插件。插件 API 表示为IUnityProfiler接口,该接口在IUnityProfiler.h标头,位于 PluginAPI 文件夹中。
| 方法 | 描述 |
|---|---|
CreateMarker |
创建一个探查器标记放置在代码中,用于描述 CPU 或 GPU 事件,然后显示在 Unity 探查器窗口中。默认添加到 Unity 代码中,或者您可以使用 ProfilerMarker API 添加自己的自定义标记。更多信息 请参阅术语表它表示命名的检测范围,然后可以使用该范围生成检测样本。 |
SetMarkerMetadataName |
指定自定义参数名称,这些参数名称可以与探查器标记的检测样本一起传递。 |
BeginSample |
开始以探查器标记命名的代码的检测部分。 |
EndSample |
结束检测部分。 |
EmitEvent |
发出带有元数据的通用事件。 |
IsEnabled |
如果探查器正在捕获数据,则返回 1。 |
IsAvailable |
对于有分析器的编辑器或开发玩家返回 1,对于发布玩家返回 0。 |
RegisterThread |
在指定名称下注册当前线程。 |
UnregisterThread |
从探查器中注销当前线程。 |
以下示例生成 Profiler 窗口可以显示的 Profiler 事件:
#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;
}
原生 Profiler 插件 API 提供了 Unity 子系统和第三方分析 API 之间的接口,因此您可以使用外部分析工具来分析您的 Unity 应用程序。这IUnityProfilerCallbacks标头公开了 API,Unity 将其存储在<UnityInstallPath>\Editor\Data\PluginAPI文件夹。(在 macOS 上,右键单击 Unity 应用程序,然后选择“显示包内容”。标头位于Contents\PluginAPI).
以下 Unity Profiler 功能有助于捕获检测数据,以便您可以分析应用程序的性能:
| 分析器功能 | 描述 |
|---|---|
| 类别 | Unity 将配置文件数据分组为类别(例如渲染、脚本和动画),并为每个类别分配一种颜色。颜色编码的类别可帮助您直观地区分探查器窗口中的数据类型。Profiler 本机插件 API 会检索这些颜色,以便您可以在外部分析工具中使用它们。 |
| 使用标志 | 使用标志充当过滤器,减少 Unity 发送到外部分析工具的数据量。在 Unity 将分析数据发送到外部工具之前,您可以使用使用标志从分析数据中删除不必要的信息。探查器将以下用法标志应用于事件标记,以便您可以筛选数据: 可用性标志 标记在 Unity 编辑器、开发播放器或发布播放器中是否可用。 详细程度 与您在编辑器中执行的任务类型以及任务所需的信息级别(例如,内部、调试或用户级别)相关。 |
| 帧事件 | 您可以使用 Profiler 本机插件 API 在外部分析工具中执行帧时分析。 |
| 线程分析 | Unity 在线程(例如,主线程、渲染线程和作业系统工作线程)上执行大量工作。您可以使用 Profiler 本机插件 API 在任何线程上启用分析。 |
要使用 Unity Profiler 在外部分析器中生成的检测数据,您可以在集成第三方分析器的 C/C++ 插件代码中使用以下最小回调集:
| 回调 | 功能 |
|---|---|
RegisterCreateCategoryCallback |
注册一个IUnityProfilerCreateCategoryCallback回调以获取性能分析器类别标识 Unity 子系统的工作负载数据(例如,渲染、脚本和动画类别)。Unity 对类别应用颜色编码,以直观地区分 Profiler 窗口中的数据类型。请参阅术语表名称和颜色,每当 Unity 创建类别时。 |
RegisterCreateMarkerCallback |
注册一个IUnityProfilerCreateMarkerCallback每当 Unity 创建标记时都会调用回调。使用它来获取标记的名称、探查器类别和用法标志。常量UnityProfilerMarkerDesc* markerDesc参数表示指向标记描述的持久指针,可用于过滤RegisterMarkerEventCallback. |
RegisterMarkerEventCallback |
注册 IUnityProfilerMarkerEventCallback 回调,Unity 在发生单次事件、作用域事件、内存分配事件或垃圾回收事件时调用该回调。然后,您可以使用此回调在外部分析工具中调用相关函数。注意:Unity 使用GC.Alloc标记和垃圾回收事件,并使用GC.Collect标记。 |
RegisterFrameCallback |
将示例封装到逻辑帧中,以便不使用帧的外部分析工具可以使用这些示例。还注册 Unity Profiler 在 Unity 启动下一个逻辑 CPU 帧时运行的回调。 |
RegisterCreateThreadCallback |
注册回调以在 Unity 注册线程进行分析时获取内部线程名称。 |
此示例演示如何将 Unity Profiler 事件传递给另一个具有推送/弹出语义的探查器。它提供两个功能:
void MyProfilerPushMarker(const char* name):推送命名标记。void MyProfilerPopMarker():pops 乐器标记。以下示例提供了将开始和结束检测事件从 Unity Profiler 传递到外部分析器所需的最小实现:
#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.
您可以动态注册和注销标记回调,每帧一次。以下示例通过启用和禁用回调来最大程度地减少分析开销,具体取决于第三方配置文件状态。
| 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.DefaultMarkerGC.Alloc
Profiler.DefaultMarker是 Unity 为 Profiler.BeginSample 和 Profiler.EndSample 事件保留的标记。
在前面的示例中,kUnityProfilerMarkerEventTypeBegin eventType对应于Profiler.BeginSample事件,并具有以下数据:
UnityEngine.Object实例 ID。如果未指定对象,则为 0。Profiler.BeginSample.大小以字节为单位。
GC.Alloc是与垃圾回收分配相对应的标记。它有以下数据: