您可以使用底层原生 插件在 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
插件 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 |
从分析器中注销当前线程。 |
以下示例生成分析器窗口可以显示的分析器事件
#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;
}
原生分析器插件 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 注册线程以进行分析时获取内部线程名称。 |
此示例向您展示如何将 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
。
您可以动态注册和注销标记回调,每帧一次。以下示例通过启用和禁用回调来最大程度地减少分析开销,具体取决于第三方分析状态。
| 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
是 Unity 为 Profiler.BeginSample 和 Profiler.EndSample 事件保留的标记。
在前面的示例中,kUnityProfilerMarkerEventTypeBegin eventType
对应于 Profiler.BeginSample
事件,并具有以下数据
UnityEngine.Object
实例 ID。如果未指定对象,则为 0。Profiler.BeginSample
的 UTF16 字符串。大小以字节为单位。
GC.Alloc
是对应于垃圾回收分配的标记。它具有以下数据