using System; using System.Runtime.InteropServices; using UnityEngine; namespace TracyProfiler { /// /// Tracy 性能分析器的 Unity 封装 /// 提供简单易用的 C# API 来使用 Tracy 性能分析功能 /// public static class Tracy { #if UNITY_IOS && !UNITY_EDITOR private const string DLL_NAME = "__Internal"; #else private const string DLL_NAME = "UnityTracyPlugin"; #endif #region Native Methods [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyInit(); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyShutdown(); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyFrameMark(); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyPlotValue(string name, double value); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracySendMessage(string message); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracySetThreadName(string name); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyZoneBegin(string name); [DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)] private static extern void TracyZoneEnd(); #endregion private static bool s_initialized = false; private static bool s_enabled = true; /// /// Tracy 是否已启用 /// public static bool Enabled { get => s_enabled; set => s_enabled = value; } /// /// Tracy 是否已初始化 /// public static bool IsInitialized => s_initialized; /// /// 初始化 Tracy /// public static void Initialize() { if (s_initialized) return; try { #if TRACY_ENABLE || UNITY_EDITOR TracyInit(); s_initialized = true; Debug.Log("[Tracy] 性能分析器已初始化"); #else Debug.Log("[Tracy] 性能分析器已禁用(编译时未定义 TRACY_ENABLE)"); #endif } catch (DllNotFoundException e) { Debug.LogWarning($"[Tracy] 未找到 Tracy Plugin DLL: {e.Message}"); s_enabled = false; } catch (Exception e) { Debug.LogError($"[Tracy] 初始化失败: {e.Message}"); s_enabled = false; } } /// /// 关闭 Tracy /// public static void Shutdown() { if (!s_initialized) return; try { TracyShutdown(); s_initialized = false; Debug.Log("[Tracy] 性能分析器已关闭"); } catch (Exception e) { Debug.LogError($"[Tracy] 关闭失败: {e.Message}"); } } /// /// 标记帧边界(通常在每帧末尾调用) /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void MarkFrame() { if (!s_initialized || !s_enabled) return; TracyFrameMark(); } /// /// 绘制数值(用于实时监控变量) /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void Plot(string name, double value) { if (!s_initialized || !s_enabled) return; TracyPlotValue(name, value); } /// /// 绘制整数值 /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void Plot(string name, int value) { Plot(name, (double)value); } /// /// 绘制浮点数值 /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void Plot(string name, float value) { Plot(name, (double)value); } /// /// 发送消息到 Tracy /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void Message(string message) { if (!s_initialized || !s_enabled) return; TracySendMessage(message); } /// /// 设置当前线程名称 /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void SetThreadName(string name) { if (!s_initialized || !s_enabled) return; TracySetThreadName(name); } /// /// Tracy Zone 的作用域包装器 /// 使用 using 语句自动管理生命周期 /// public struct ZoneScope : IDisposable { private bool isValid; private string zoneName; public ZoneScope(string name) { zoneName = name; isValid = s_initialized && s_enabled; #if TRACY_ENABLE if (isValid) { TracyZoneBegin(name); } #endif } public void Dispose() { #if TRACY_ENABLE if (isValid && s_initialized && s_enabled) { TracyZoneEnd(); } #endif } } /// /// 创建一个 Tracy Zone(性能追踪区域) /// 使用 using 语句确保自动结束 /// /// /// using (Tracy.Zone("MyFunction")) /// { /// // 要追踪的代码 /// } /// public static ZoneScope Zone(string name) { return new ZoneScope(name); } /// /// 开始一个命名的 Zone /// 注意:必须手动调用 EndZone() 结束,推荐使用 Zone() 方法配合 using 语句 /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void BeginZone(string name) { if (!s_initialized || !s_enabled) return; TracyZoneBegin(name); } /// /// 结束当前 Zone /// 注意:必须与 BeginZone() 配对使用 /// [System.Diagnostics.Conditional("TRACY_ENABLE")] public static void EndZone() { if (!s_initialized || !s_enabled) return; TracyZoneEnd(); } } /// /// Tracy Zone 的属性标记版本 /// 可以标记在方法上,自动追踪整个方法 /// 注意:需要配合 AOP 或代码生成工具使用 /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public class TracyZoneAttribute : Attribute { public string Name { get; set; } public TracyZoneAttribute(string name = null) { Name = name; } } }