版本:Unity 6 (6000.0)
语言:英语
XR SDK 预初始化接口
Unity 服务

XR SDK 统计接口

XR SDK 统计接口用于注册和管理统计数据。XR一个涵盖虚拟现实 (VR)、增强现实 (AR) 和混合现实 (MR) 应用程序的总称。支持这些形式的交互式应用程序的设备可以称为 XR 设备。更多信息
参见 术语表

概述

使用 XR 统计接口在各个子系统之间记录统计数据。唯一支持的统计原始数据类型是浮点数。

使用 UnityPluginLoad 入口点方法获取指向 XRStats 接口的指针

IUnityXRStats* sXRStats = nullptr;

extern "C" void UNITY_INTERFACE_EXPORT UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    sXRStats = (IUnityXRStats*)unityInterfaces->GetInterface(UNITY_GET_INTERFACE_GUID(IUnityXRStats));
    //...
}

用法

使用统计接口注册您的子系统和各个统计数据定义

static UnityXRStatId m_GPUFrameTimeID;
static UnityXRStatId m_DroppedFrameCountID;
static UnityXRStatId m_WorkThreadStat;

static UnitySubsystemErrorCode ExampleDisplayProvider_Start(UnitySubsystemHandle handle)
{
    if (sXRStats)
    {
        sXRStats->RegisterStatSource(handle);
        m_GPUFrameTimeID = sXRStats->RegisterStatDefinition(handle, "Example.GPUTime", kUnityXRStatOptionNone);
        m_DroppedFrameCountID = sXRStats->RegisterStatDefinition(handle, "Example.DroppedFrame", kUnityXRStatOptionNone);
        m_WorkThreadStat = sXRStats->RegisterStatDefinition(handle, "Example.WorkerThreadStat", kUnityXRStatOptionNone);
    }

    return kUnitySubsystemErrorCodeSuccess;
}

在 Gfx 线程上更新统计数据

extern float GetLastGPUTime(); //provided by your runtime
static void ExampleDisplayProvider_GfxThreadCall(UnitySubsystemHandle handle)
{
    sXRStats->SetStatFloat(m_GPUFrameTimeID, GetLastGPUTime());
    // Do gfx thread things
}

在主线程上更新统计数据

extern float GetDroppedFrameCount(); //provided by your runtime

static void ExampleDisplayProvider_MainThreadCall(UnitySubsystemHandle handle)
{
    sXRStats->SetStatFloat(m_DroppedFrameCountID, GetDroppedFrameCount());
    // Do main thread things
}

在您自己的线程上更新统计数据,但请务必调用 IncrementStatFrame 以使该线程的当前帧与其他线程保持同步(主线程和图形线程内部会管理此操作)

extern float GetWorkerThreadStat(); //provided by your runtime
static void ExampleDisplayProvider_MyWorkerThread(UnitySubsystemHandle handle)
{
    sXRStats->IncrementStatFrame();
    sXRStats->SetStatFloat(m_WorkThreadStat, GetWorkerThreadStat());
    // Do worker thread things
}

子系统停止时取消注册统计数据源

static void ExampleDisplayProvider_Stop(UnitySubsystemHandle handle)
{
    sXRStats->UnregisterStatSource(handle);
}

线程安全

通过 SetStatFloat 更新统计数据是线程安全的。但是,注册和取消注册统计数据源不是线程安全的,只能在统计数据源生命周期的 Start 和 Stop 函数期间的主线程上执行。

限制

处理统计数据的队列大小为 2000。此队列在所有线程和所有子系统之间共享,并且仅在帧完成时进行服务。因此,您应尽量减少对 SetStatFloat 的调用次数,以避免填满队列。

注意:队列已满时记录的任何统计数据都将丢失。

向用户公开统计数据

UnityEngine.XR.Provider 命名空间中,使用 public static bool TryGetStat(Experimental.IntegratedSubsystem xrSubsystem, string tag, out float value) 获取已注册并使用您的提供程序更新的统计数据

using UnityEngine.XR.Provider;
using System.Collections.Generic;
using UnityEngine.Experimental.XR;
using UnityEngine.Experimental;
using UnityEngine;

public static class ExampleProviderStats
{
    public static float GPUFrameTime()
    {
        float tmp;
        XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.GPUTime", out tmp);
        return tmp;
    }

    public static int DroppedFrameCount()
    {
        float tmp;
        XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.DroppedFrame", out tmp);
        return (int)tmp;
    }

    public static float MyWorkerThreadStat()
    {
        float tmp;
        XRStats.TryGetStat(GetFirstDisplaySubsystem(), "Example.WorkerThreadStat", out tmp);
        return tmp;
    }

    // etc...
    private static IntegratedSubsystem GetFirstDisplaySubsystem()
    {
        List<XRDisplaySubsystem> displays = new List<XRDisplaySubsystem>();
        SubsystemManager.GetInstances(displays);
        if (displays.Count == 0)
        {
            Debug.Log("No display subsystem found.");
            return null;
        }
        return displays[0];
    }
}

编写如上例所示的公共访问器方法可以帮助用户获取统计数据,而无需筛选提供程序文档并查找已注册统计数据的子系统。

此外,某些子系统具有预定义的统计数据标签。您的提供程序可以通过注册特定于子系统的统计数据标签(例如:Headers/XR/UnityXRDisplayStats.h)来为 Unity 公开的预定义统计数据 API提供统计数据。

XR SDK 预初始化接口
Unity 服务