Files
tracy-for-unity/unity_examples/TracyManager.cs

270 lines
7.7 KiB
C#
Raw Permalink Normal View History

2025-11-26 14:35:58 +08:00
using UnityEngine;
using UnityEngine.Profiling;
namespace TracyProfiler
{
/// <summary>
/// Tracy 管理器 - 负责初始化和每帧更新
/// 在场景中添加此组件以启用 Tracy 性能分析
/// </summary>
[DefaultExecutionOrder(-9999)] // 确保最早执行
public class TracyManager : MonoBehaviour
{
[Header("Tracy 设置")]
[Tooltip("启动时自动初始化 Tracy")]
[SerializeField] private bool enableOnStart = true;
[Tooltip("每帧自动标记帧边界")]
[SerializeField] private bool markFrames = true;
[Header("性能监控")]
[Tooltip("监控帧率和帧时间")]
[SerializeField] private bool monitorFrameRate = true;
[Tooltip("监控内存使用")]
[SerializeField] private bool monitorMemory = true;
[Tooltip("监控渲染统计")]
[SerializeField] private bool monitorRendering = true;
[Tooltip("监控物理系统")]
[SerializeField] private bool monitorPhysics = true;
[Header("高级选项")]
[Tooltip("在编辑器中也启用 Tracy")]
[SerializeField] private bool enableInEditor = true;
[Tooltip("显示调试信息")]
[SerializeField] private bool showDebugInfo = false;
private static TracyManager instance;
public static TracyManager Instance => instance;
private void Awake()
{
// 单例模式
if (instance != null && instance != this)
{
Debug.LogWarning("[Tracy] 检测到多个 TracyManager 实例,销毁多余的实例");
Destroy(gameObject);
return;
}
instance = this;
DontDestroyOnLoad(gameObject);
// 编辑器检查
if (!Application.isPlaying)
return;
#if UNITY_EDITOR
if (!enableInEditor)
{
Debug.Log("[Tracy] 编辑器模式下已禁用");
return;
}
#endif
// 初始化 Tracy
if (enableOnStart)
{
Tracy.Initialize();
if (Tracy.IsInitialized)
{
Tracy.Message("Unity Application Started");
Tracy.SetThreadName("Main Thread");
if (showDebugInfo)
{
LogSystemInfo();
}
}
}
}
private void Update()
{
using (Tracy.Zone("TracyManager.Update"))
{
// 监控帧率
if (monitorFrameRate)
{
MonitorFrameRate();
}
// 监控内存
if (monitorMemory)
{
MonitorMemory();
}
}
}
private void LateUpdate()
{
using (Tracy.Zone("TracyManager.LateUpdate"))
{
// 在每帧末尾标记帧边界
if (markFrames)
{
Tracy.MarkFrame();
}
// 监控渲染统计
if (monitorRendering)
{
MonitorRendering();
}
}
}
private void FixedUpdate()
{
using (Tracy.Zone("TracyManager.FixedUpdate"))
{
// 监控物理系统
if (monitorPhysics)
{
MonitorPhysics();
}
}
}
private void OnDestroy()
{
if (instance == this)
{
Tracy.Message("Unity Application Shutting Down");
Tracy.Shutdown();
instance = null;
}
}
private void OnApplicationQuit()
{
Tracy.Message("Unity Application Quit");
Tracy.Shutdown();
}
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
{
Tracy.Message("Application Paused");
}
else
{
Tracy.Message("Application Resumed");
}
}
#region Performance Monitoring
private void MonitorFrameRate()
{
float fps = 1.0f / Time.unscaledDeltaTime;
float frameTime = Time.unscaledDeltaTime * 1000.0f;
Tracy.Plot("FPS", fps);
Tracy.Plot("Frame Time (ms)", frameTime);
Tracy.Plot("Time Scale", Time.timeScale);
}
private void MonitorMemory()
{
// GC 内存
long totalMemory = System.GC.GetTotalMemory(false);
Tracy.Plot("GC Memory (MB)", totalMemory / (1024.0 * 1024.0));
// Unity Profiler 内存统计
long usedHeap = Profiler.usedHeapSizeLong;
long totalAllocated = Profiler.GetTotalAllocatedMemoryLong();
long totalReserved = Profiler.GetTotalReservedMemoryLong();
Tracy.Plot("Used Heap (MB)", usedHeap / (1024.0 * 1024.0));
Tracy.Plot("Total Allocated (MB)", totalAllocated / (1024.0 * 1024.0));
Tracy.Plot("Total Reserved (MB)", totalReserved / (1024.0 * 1024.0));
// 纹理内存
Tracy.Plot("Texture Memory (MB)", Profiler.GetAllocatedMemoryForGraphicsDriver() / (1024.0 * 1024.0));
}
private void MonitorRendering()
{
// 渲染统计
Tracy.Plot("SetPass Calls", Profiler.GetRuntimeMemorySizeLong(null));
Tracy.Plot("Draw Calls", UnityEngine.Rendering.FrameTimingManager.GetLatestTimings(1, null));
Tracy.Plot("Triangles", 0); // 需要通过 Stats 获取
Tracy.Plot("Vertices", 0); // 需要通过 Stats 获取
}
private void MonitorPhysics()
{
// 物理对象计数
int rigidbodyCount = FindObjectsOfType<Rigidbody>().Length;
int colliderCount = FindObjectsOfType<Collider>().Length;
Tracy.Plot("Rigidbody Count", rigidbodyCount);
Tracy.Plot("Collider Count", colliderCount);
}
private void LogSystemInfo()
{
Tracy.Message($"Device: {SystemInfo.deviceModel}");
Tracy.Message($"OS: {SystemInfo.operatingSystem}");
Tracy.Message($"CPU: {SystemInfo.processorType} ({SystemInfo.processorCount} cores)");
Tracy.Message($"Memory: {SystemInfo.systemMemorySize} MB");
Tracy.Message($"GPU: {SystemInfo.graphicsDeviceName}");
Tracy.Message($"Graphics API: {SystemInfo.graphicsDeviceType}");
Tracy.Message($"Unity Version: {Application.unityVersion}");
}
#endregion
#region Public API
/// <summary>
/// 手动触发帧标记(如果禁用了自动标记)
/// </summary>
public void ManualFrameMark()
{
Tracy.MarkFrame();
}
/// <summary>
/// 发送自定义消息
/// </summary>
public void SendMessage(string message)
{
Tracy.Message(message);
}
/// <summary>
/// 绘制自定义数值
/// </summary>
public void PlotValue(string name, double value)
{
Tracy.Plot(name, value);
}
#endregion
#if UNITY_EDITOR
private void OnValidate()
{
// 在编辑器中修改参数时的验证
if (!Application.isPlaying)
return;
if (enableOnStart && !Tracy.IsInitialized)
{
Tracy.Initialize();
}
}
#endif
}
}