refactor: 性能分析工具,暂时无用

This commit is contained in:
2026-03-27 15:18:06 +08:00
parent 8c0d53c2a1
commit 24d0536634
6 changed files with 0 additions and 1008 deletions
@@ -1,238 +0,0 @@
# Unity游戏性能优化指南
## 概述
本文档提供了针对您的Unity游戏的性能优化建议和解决方案。
## 已发现的性能问题
### 1. FindObjectOfType过度使用
**问题位置:**
- `ClueManager.cs` - 第24行
- `MemoryClueSlot.cs` - 第13行
- `ClueSlot.cs` - 第23行
- `ClueInteraction.cs` - 第34行
- `MemoryProcess.cs` - 第87、96行
**解决方案:**
- 在Start/Awake中缓存组件引用
- 使用单例模式或依赖注入
- 避免在Update中调用FindObjectOfType
### 2. Update方法中的复杂计算
**问题位置:**
- `UIManager.cs` - 第27行
- `MainPanel.cs` - 第29行
**解决方案:**
- 使用协程替代Update中的复杂逻辑
- 减少每帧的计算量
- 使用事件驱动架构
### 3. 频繁的对象创建和销毁
**问题位置:**
- `ClueManager.cs` - 第35、58行(Instantiate调用)
**解决方案:**
- 使用对象池管理频繁创建的对象
- 预加载常用资源
- 复用对象而不是重新创建
## 性能优化工具
### 1. PerformanceProfiler
实时监控游戏性能指标:
- FPS监控
- 内存使用情况
- 绘制调用数量
- 批处理数量
- 三角形和顶点数量
**使用方法:**
1. 将PerformanceProfiler组件添加到场景中的GameObject
2. 在Inspector中配置监控选项
3. 运行游戏查看实时性能数据
### 2. PerformanceOptimizer
提供具体的优化建议:
- 自动分析性能瓶颈
- 生成优化建议报告
- 提供自动优化选项
**使用方法:**
1. 将PerformanceOptimizer组件添加到场景中
2. 确保场景中有PerformanceProfiler组件
3. 运行游戏查看优化建议
### 3. ObjectPool
管理对象池,减少内存分配:
- 预创建对象池
- 复用对象而不是重新创建
- 自动管理对象生命周期
**使用方法:**
1. 将ObjectPool组件添加到场景中
2. 在Inspector中配置需要池化的预制体
3. 使用GetFromPool和ReturnToPool方法
## 具体优化建议
### 代码层面优化
#### 1. 缓存组件引用
```csharp
// 优化前
void Update()
{
var manager = FindObjectOfType<GameManager>();
manager.DoSomething();
}
// 优化后
private GameManager _gameManager;
void Start()
{
_gameManager = FindObjectOfType<GameManager>();
}
void Update()
{
_gameManager.DoSomething();
}
```
#### 2. 使用对象池
```csharp
// 优化前
GameObject obj = Instantiate(prefab);
Destroy(obj, 2f);
// 优化后
GameObject obj = ObjectPool.Instance.GetFromPool("prefabTag");
ObjectPool.Instance.ReturnToPool(obj, 2f);
```
#### 3. 优化Update方法
```csharp
// 优化前
void Update()
{
// 复杂的计算逻辑
if (Time.frameCount % 30 == 0) // 每30帧执行一次
{
// 复杂计算
}
}
// 优化后
void Start()
{
StartCoroutine(ComplexCalculationCoroutine());
}
IEnumerator ComplexCalculationCoroutine()
{
while (true)
{
// 复杂计算
yield return new WaitForSeconds(0.5f); // 每0.5秒执行一次
}
}
```
### 渲染优化
#### 1. 减少绘制调用
- 合并使用相同材质的对象
- 使用静态批处理
- 减少透明物体的使用
#### 2. 优化UI
- 减少Canvas数量
- 使用Canvas Group管理UI层级
- 避免频繁的UI更新
#### 3. 纹理优化
- 使用适当的纹理压缩格式
- 减少纹理大小
- 使用纹理图集
### 内存优化
#### 1. 资源管理
- 及时释放不需要的资源
- 使用Resources.UnloadUnusedAssets()
- 避免内存泄漏
#### 2. 对象生命周期管理
- 使用对象池管理频繁创建的对象
- 及时销毁不需要的对象
- 避免在Update中创建临时对象
## 实施步骤
### 第一步:添加性能监控
1. 在场景中添加PerformanceProfiler组件
2. 运行游戏,观察性能指标
3. 记录性能瓶颈
### 第二步:应用代码优化
1. 替换FindObjectOfType调用为缓存引用
2. 优化Update方法中的复杂逻辑
3. 使用对象池管理频繁创建的对象
### 第三步:渲染优化
1. 检查绘制调用数量
2. 优化材质和纹理
3. 调整UI结构
### 第四步:测试和验证
1. 运行性能测试
2. 对比优化前后的性能数据
3. 确保功能正常
## 监控指标
### 目标性能指标
- FPS: 60+ (移动设备30+)
- 内存使用: <200MB
- 绘制调用: <100
- 批处理: <50
### 警告阈值
- FPS < 30
- 内存使用 > 200MB
- 绘制调用 > 100
- 批处理 > 50
## 常见问题解决
### Q: FPS突然下降怎么办?
A:
1. 检查是否有大量对象同时创建
2. 查看Profiler中的CPU使用情况
3. 检查Update方法中的复杂计算
### Q: 内存使用过高怎么办?
A:
1. 检查是否有内存泄漏
2. 使用对象池减少内存分配
3. 及时释放不需要的资源
### Q: 绘制调用过多怎么办?
A:
1. 合并使用相同材质的对象
2. 使用静态批处理
3. 减少透明物体的使用
## 总结
通过实施这些优化措施,您的游戏性能应该会有显著提升。建议按照以下顺序进行优化:
1. 首先添加性能监控工具
2. 识别具体的性能瓶颈
3. 应用代码层面的优化
4. 进行渲染优化
5. 测试和验证优化效果
记住,性能优化是一个持续的过程,需要不断监控和改进。
@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: f5866f6b185f1cc4a975bed9bd50cc3c
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,192 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
namespace AibisDream.Utility
{
/// <summary>
/// 性能优化建议工具
/// </summary>
public class PerformanceOptimizer : MonoBehaviour
{
[Header("优化建议设置")]
public bool enableOptimizationTips = true;
public bool autoApplyOptimizations = false;
[Header("性能阈值")]
public float targetFPS = 60f;
public float maxMemoryUsage = 200f; // MB
public int maxDrawCalls = 100;
public int maxBatches = 50;
private PerformanceProfiler profiler;
private List<string> optimizationTips = new List<string>();
private void Start()
{
profiler = FindObjectOfType<PerformanceProfiler>();
if (profiler == null)
{
Debug.LogWarning("未找到PerformanceProfiler组件,请先添加性能分析器");
return;
}
if (enableOptimizationTips)
{
StartCoroutine(OptimizationMonitor());
}
}
private System.Collections.IEnumerator OptimizationMonitor()
{
while (enableOptimizationTips)
{
AnalyzePerformance();
yield return new WaitForSeconds(5f); // 每5秒分析一次
}
}
private void AnalyzePerformance()
{
optimizationTips.Clear();
if (profiler == null) return;
float fps = profiler.GetFPS();
float memory = profiler.GetMemoryUsage();
int drawCalls = profiler.GetDrawCalls();
int batches = profiler.GetBatches();
// FPS优化建议
if (fps < targetFPS)
{
optimizationTips.Add("FPS优化建议:");
optimizationTips.Add("• 减少Update方法中的复杂计算");
optimizationTips.Add("• 使用对象池减少Instantiate/Destroy调用");
optimizationTips.Add("• 优化FindObjectOfType调用,缓存组件引用");
optimizationTips.Add("• 减少每帧的GetComponent调用");
optimizationTips.Add("• 使用协程替代Update中的复杂逻辑");
}
// 内存优化建议
if (memory > maxMemoryUsage)
{
optimizationTips.Add("内存优化建议:");
optimizationTips.Add("• 及时释放不需要的资源");
optimizationTips.Add("• 使用对象池管理频繁创建的对象");
optimizationTips.Add("• 检查是否有内存泄漏");
optimizationTips.Add("• 优化纹理压缩设置");
optimizationTips.Add("• 减少不必要的MonoBehaviour组件");
}
// 渲染优化建议
if (drawCalls > maxDrawCalls || batches > maxBatches)
{
optimizationTips.Add("渲染优化建议:");
optimizationTips.Add("• 合并使用相同材质的对象");
optimizationTips.Add("• 使用静态批处理(Static Batching)");
optimizationTips.Add("• 减少透明物体的使用");
optimizationTips.Add("• 优化UI Canvas的层级结构");
optimizationTips.Add("• 使用LOD系统减少远处物体的细节");
}
// 通用优化建议
optimizationTips.Add("通用优化建议:");
optimizationTips.Add("• 使用Profiler分析具体瓶颈");
optimizationTips.Add("• 启用Unity的Burst编译");
optimizationTips.Add("• 使用Job System进行多线程计算");
optimizationTips.Add("• 优化协程和异步操作");
optimizationTips.Add("• 减少字符串连接操作,使用StringBuilder");
}
/// <summary>
/// 获取优化建议
/// </summary>
public List<string> GetOptimizationTips()
{
return new List<string>(optimizationTips);
}
/// <summary>
/// 打印优化建议到控制台
/// </summary>
public void PrintOptimizationTips()
{
if (optimizationTips.Count == 0)
{
Debug.Log("当前性能表现良好,无需优化");
return;
}
Debug.Log("=== 性能优化建议 ===");
foreach (string tip in optimizationTips)
{
Debug.Log(tip);
}
}
/// <summary>
/// 应用自动优化
/// </summary>
public void ApplyAutoOptimizations()
{
if (!autoApplyOptimizations) return;
Debug.Log("应用自动优化...");
// 自动优化示例
OptimizeUpdateMethods();
OptimizeFindObjectOfTypeCalls();
OptimizeGetComponentCalls();
}
private void OptimizeUpdateMethods()
{
// 查找所有Update方法并给出建议
MonoBehaviour[] allMonoBehaviours = FindObjectsOfType<MonoBehaviour>();
foreach (MonoBehaviour mb in allMonoBehaviours)
{
if (mb.GetType().GetMethod("Update") != null)
{
// 这里可以添加具体的优化逻辑
Debug.Log($"发现Update方法: {mb.GetType().Name}");
}
}
}
private void OptimizeFindObjectOfTypeCalls()
{
// 查找所有FindObjectOfType调用
Debug.Log("建议将FindObjectOfType调用移到Start/Awake中缓存结果");
}
private void OptimizeGetComponentCalls()
{
// 查找所有GetComponent调用
Debug.Log("建议缓存GetComponent的结果,避免重复调用");
}
/// <summary>
/// 创建性能优化报告
/// </summary>
public void CreatePerformanceReport()
{
if (profiler == null) return;
string report = "=== 性能报告 ===\n";
report += $"FPS: {profiler.GetFPS():F1}\n";
report += $"内存使用: {profiler.GetMemoryUsage():F1}MB\n";
report += $"绘制调用: {profiler.GetDrawCalls()}\n";
report += $"批处理: {profiler.GetBatches()}\n";
report += "\n优化建议:\n";
foreach (string tip in optimizationTips)
{
report += tip + "\n";
}
Debug.Log(report);
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fa69d1942a5d5414c92100b235a71e21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,549 +0,0 @@
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
using Unity.Profiling;
using System.Diagnostics;
using Debug = UnityEngine.Debug;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace AibisDream.Utility
{
/// <summary>
/// 性能分析工具,用于监控游戏性能
/// </summary>
public class PerformanceProfiler : MonoBehaviour
{
[Header("性能监控设置")]
public bool enableProfiling = true;
public bool showFPS = true;
public bool showMemory = true;
public bool showDrawCalls = true;
public bool showBatches = true;
public bool showTris = true;
public bool showVerts = true;
[Header("数据记录设置")]
public bool enableCsvLogging = false;
public float logInterval = 0.5f; // 秒
public string csvFileName = "performance_log";
[Header("性能警告阈值")]
public float fpsWarningThreshold = 30f;
public float memoryWarningThreshold = 100f; // MB
public int drawCallWarningThreshold = 100;
public int batchWarningThreshold = 50;
[Header("显示设置")]
public Color normalColor = Color.white;
public Color warningColor = Color.yellow;
public Color errorColor = Color.red;
public int fontSize = 14;
[Header("CPU/GPU 时间分析")]
public bool showCPUTime = true;
public bool showGPUTime = true;
public float cpuTimeWarningThreshold = 16.67f; // 60fps对应的帧时间
public float gpuTimeWarningThreshold = 16.67f;
[Header("GC监控")]
public bool showGCStats = true;
public int gcWarningThreshold = 5; // 每秒GC次数警告阈值
[Header("资源监控")]
public bool showResourceStats = true;
public long textureMemoryWarningThreshold = 1024; // MB
public long meshMemoryWarningThreshold = 512; // MB
[Header("系统性能分析")]
public bool enableSystemProfiling = true;
public float systemTimeWarningThreshold = 8f; // ms
private float deltaTime = 0.0f;
private float cpuFrameTime;
private float gpuFrameTime;
private long lastGCCount;
private float gcTimeAccumulator;
private int gcCountInLastSecond;
private int loadedTextureCount;
private int loadedMeshCount;
private long totalTextureMemory;
private long totalMeshMemory;
private Dictionary<string, CustomProfiler> systemProfilers = new Dictionary<string, CustomProfiler>();
public class CustomProfiler
{
public string name;
public float totalTime;
public float maxTime;
public int sampleCount;
public Stopwatch stopwatch;
public float AverageTime => sampleCount > 0 ? totalTime / sampleCount : 0;
public void Reset()
{
totalTime = 0;
maxTime = 0;
sampleCount = 0;
stopwatch = new Stopwatch();
}
}
private float fps = 0.0f;
private float memoryUsage = 0.0f;
private int drawCalls = 0;
private int batches = 0;
private int triangles = 0;
private int vertices = 0;
private GUIStyle style;
private List<string> performanceWarnings = new List<string>();
// CSV 日志
private StreamWriter csvWriter;
private float nextLogTime = 0f;
private string logFilePath;
private void Start()
{
if (!enableProfiling) return;
// 创建GUI样式
style = new GUIStyle();
style.fontSize = fontSize;
style.normal.textColor = normalColor;
// 启动性能监控协程
StartCoroutine(PerformanceMonitor());
// 初始化CSV日志
if (enableCsvLogging)
{
InitCsvLogging();
}
}
private void Update()
{
if (!enableProfiling) return;
// 计算FPS
deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f;
fps = 1.0f / deltaTime;
// 获取渲染统计信息
#if UNITY_EDITOR
drawCalls = UnityEditor.UnityStats.drawCalls;
batches = UnityEditor.UnityStats.batches;
triangles = UnityEditor.UnityStats.triangles;
vertices = UnityEditor.UnityStats.vertices;
#else
drawCalls = 0;
batches = 0;
triangles = 0;
vertices = 0;
#endif
// 获取内存使用情况
memoryUsage = Profiler.GetTotalAllocatedMemoryLong() / (1024f * 1024f); // 转换为MB
// CPU和GPU时间
cpuFrameTime = Time.unscaledDeltaTime * 1000f; // 转换为毫秒
if (FrameTimingManager.IsFeatureEnabled())
{
var frameData = new FrameTiming[1];
FrameTimingManager.GetLatestTimings(1, frameData);
if (frameData.Length > 0)
{
gpuFrameTime = (float)frameData[0].gpuFrameTime;
}
}
// GC监控
if (System.GC.CollectionCount(0) > lastGCCount)
{
gcCountInLastSecond++;
lastGCCount = System.GC.CollectionCount(0);
}
// 资源监控
if (showResourceStats)
{
var textures = Resources.FindObjectsOfTypeAll<Texture>();
var meshes = Resources.FindObjectsOfTypeAll<Mesh>();
loadedTextureCount = textures.Length;
loadedMeshCount = meshes.Length;
totalTextureMemory = 0;
foreach (var tex in textures)
{
if (tex != null)
totalTextureMemory += Profiler.GetRuntimeMemorySizeLong(tex);
}
totalMeshMemory = 0;
foreach (var mesh in meshes)
{
if (mesh != null)
totalMeshMemory += Profiler.GetRuntimeMemorySizeLong(mesh);
}
}
// 按间隔写入CSV
if (enableCsvLogging && csvWriter != null && Time.unscaledTime >= nextLogTime)
{
WriteCsvRow();
nextLogTime = Time.unscaledTime + Mathf.Max(0.05f, logInterval);
gcCountInLastSecond = 0; // 重置GC计数器
}
}
private System.Collections.IEnumerator PerformanceMonitor()
{
while (enableProfiling)
{
performanceWarnings.Clear();
// 检查FPS
if (fps < fpsWarningThreshold)
{
performanceWarnings.Add($"FPS过低: {fps:F1}");
}
// 检查内存使用
if (memoryUsage > memoryWarningThreshold)
{
performanceWarnings.Add($"内存使用过高: {memoryUsage:F1}MB");
}
// 检查绘制调用
if (drawCalls > drawCallWarningThreshold)
{
performanceWarnings.Add($"绘制调用过多: {drawCalls}");
}
// 检查批处理
if (batches > batchWarningThreshold)
{
performanceWarnings.Add($"批处理过多: {batches}");
}
yield return new WaitForSeconds(1f);
}
}
private void OnGUI()
{
if (!enableProfiling) return;
float yPos = 10f;
float lineHeight = fontSize + 5f;
// 显示FPS
if (showFPS)
{
Color fpsColor = fps < fpsWarningThreshold ? errorColor : normalColor;
style.normal.textColor = fpsColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"FPS: {fps:F1}", style);
yPos += lineHeight;
}
// 显示内存使用
if (showMemory)
{
Color memColor = memoryUsage > memoryWarningThreshold ? warningColor : normalColor;
style.normal.textColor = memColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"内存: {memoryUsage:F1}MB", style);
yPos += lineHeight;
}
// 显示绘制调用
if (showDrawCalls)
{
Color drawColor = drawCalls > drawCallWarningThreshold ? warningColor : normalColor;
style.normal.textColor = drawColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"绘制调用: {drawCalls}", style);
yPos += lineHeight;
}
// 显示批处理
if (showBatches)
{
Color batchColor = batches > batchWarningThreshold ? warningColor : normalColor;
style.normal.textColor = batchColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"批处理: {batches}", style);
yPos += lineHeight;
}
// 显示三角形数量
if (showTris)
{
style.normal.textColor = normalColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"三角形: {triangles:N0}", style);
yPos += lineHeight;
}
// 显示顶点数量
if (showVerts)
{
style.normal.textColor = normalColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"顶点: {vertices:N0}", style);
yPos += lineHeight;
}
// 显示CPU时间
if (showCPUTime)
{
Color timeColor = cpuFrameTime > cpuTimeWarningThreshold ? warningColor : normalColor;
style.normal.textColor = timeColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"CPU时间: {cpuFrameTime:F2}ms", style);
yPos += lineHeight;
}
// 显示GPU时间
if (showGPUTime && FrameTimingManager.IsFeatureEnabled())
{
Color timeColor = gpuFrameTime > gpuTimeWarningThreshold ? warningColor : normalColor;
style.normal.textColor = timeColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"GPU时间: {gpuFrameTime:F2}ms", style);
yPos += lineHeight;
}
// 显示GC信息
if (showGCStats)
{
Color gcColor = gcCountInLastSecond > gcWarningThreshold ? warningColor : normalColor;
style.normal.textColor = gcColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), $"GC次数/秒: {gcCountInLastSecond}", style);
yPos += lineHeight;
}
// 显示资源信息
if (showResourceStats)
{
yPos += 10f;
style.normal.textColor = normalColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), "资源统计:", style);
yPos += lineHeight;
Color texMemColor = (totalTextureMemory / (1024f * 1024f)) > textureMemoryWarningThreshold ? warningColor : normalColor;
style.normal.textColor = texMemColor;
GUI.Label(new Rect(20, yPos, 300, lineHeight),
$"贴图: {loadedTextureCount}个 ({totalTextureMemory / (1024f * 1024f):F1}MB)", style);
yPos += lineHeight;
Color meshMemColor = (totalMeshMemory / (1024f * 1024f)) > meshMemoryWarningThreshold ? warningColor : normalColor;
style.normal.textColor = meshMemColor;
GUI.Label(new Rect(20, yPos, 300, lineHeight),
$"网格: {loadedMeshCount}个 ({totalMeshMemory / (1024f * 1024f):F1}MB)", style);
yPos += lineHeight;
}
// 显示系统性能分析
if (enableSystemProfiling && systemProfilers.Count > 0)
{
yPos += 10f;
style.normal.textColor = normalColor;
GUI.Label(new Rect(10, yPos, 200, lineHeight), "系统性能:", style);
yPos += lineHeight;
foreach (var profiler in systemProfilers.Values)
{
if (profiler.sampleCount > 0)
{
Color timeColor = profiler.AverageTime > systemTimeWarningThreshold ? warningColor : normalColor;
style.normal.textColor = timeColor;
GUI.Label(new Rect(20, yPos, 400, lineHeight),
$"{profiler.name}: {profiler.AverageTime:F2}ms (最大: {profiler.maxTime:F2}ms)", style);
yPos += lineHeight;
}
}
}
// 显示性能警告
if (performanceWarnings.Count > 0)
{
yPos += 10f;
style.normal.textColor = errorColor;
GUI.Label(new Rect(10, yPos, 400, lineHeight), "性能警告:", style);
yPos += lineHeight;
foreach (string warning in performanceWarnings)
{
GUI.Label(new Rect(20, yPos, 400, lineHeight), $"• {warning}", style);
yPos += lineHeight;
}
}
}
/// <summary>
/// 获取当前FPS
/// </summary>
public float GetFPS()
{
return fps;
}
/// <summary>
/// 获取内存使用量(MB
/// </summary>
public float GetMemoryUsage()
{
return memoryUsage;
}
/// <summary>
/// 获取绘制调用数量
/// </summary>
public int GetDrawCalls()
{
return drawCalls;
}
/// <summary>
/// 获取批处理数量
/// </summary>
public int GetBatches()
{
return batches;
}
/// <summary>
/// 记录性能数据到日志
/// </summary>
public void LogPerformanceData()
{
Debug.Log($"[性能数据] FPS: {fps:F1}, 内存: {memoryUsage:F1}MB, 绘制调用: {drawCalls}, 批处理: {batches}");
}
private void OnDisable()
{
CloseCsv();
}
private void OnDestroy()
{
CloseCsv();
}
private void InitCsvLogging()
{
try
{
var directory = Application.persistentDataPath;
logFilePath = Path.Combine(directory, $"perf_{System.DateTime.Now:yyyyMMdd_HHmmss}.csv");
csvWriter = new StreamWriter(new FileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite));
csvWriter.WriteLine("time,fps,memoryMB,drawCalls,batches,triangles,vertices,cpuTime,gpuTime,gcCount," +
"textureCount,meshCount,textureMemoryMB,meshMemoryMB");
csvWriter.Flush();
nextLogTime = Time.unscaledTime + Mathf.Max(0.05f, logInterval);
Debug.Log($"性能CSV日志: {logFilePath}");
}
catch (System.Exception e)
{
Debug.LogWarning($"初始化CSV日志失败: {e.Message}");
enableCsvLogging = false;
}
}
private void WriteCsvRow()
{
try
{
if (csvWriter == null) return;
csvWriter.WriteLine($"{Time.unscaledTime:F3},{fps:F2},{memoryUsage:F1},{drawCalls},{batches},{triangles},{vertices}," +
$"{cpuFrameTime:F2},{gpuFrameTime:F2},{gcCountInLastSecond}," +
$"{loadedTextureCount},{loadedMeshCount},{totalTextureMemory/1024/1024:F1},{totalMeshMemory/1024/1024:F1}");
csvWriter.Flush();
}
catch (System.Exception e)
{
Debug.LogWarning($"写入CSV失败: {e.Message}");
}
}
private void CloseCsv()
{
try
{
if (csvWriter != null)
{
csvWriter.Flush();
csvWriter.Close();
csvWriter.Dispose();
csvWriter = null;
}
}
catch {}
}
public string GetLogFilePath()
{
return logFilePath;
}
/// <summary>
/// 开始系统性能采样
/// </summary>
public void BeginSample(string systemName)
{
if (!enableSystemProfiling) return;
if (!systemProfilers.ContainsKey(systemName))
{
systemProfilers[systemName] = new CustomProfiler
{
name = systemName,
stopwatch = new Stopwatch()
};
}
systemProfilers[systemName].stopwatch.Start();
}
/// <summary>
/// 结束系统性能采样
/// </summary>
public void EndSample(string systemName)
{
if (!enableSystemProfiling) return;
if (systemProfilers.TryGetValue(systemName, out var profiler))
{
profiler.stopwatch.Stop();
float time = profiler.stopwatch.ElapsedTicks / (float)System.TimeSpan.TicksPerMillisecond;
profiler.totalTime += time;
profiler.maxTime = Mathf.Max(profiler.maxTime, time);
profiler.sampleCount++;
profiler.stopwatch.Reset();
}
}
/// <summary>
/// 重置所有系统性能分析器
/// </summary>
public void ResetAllProfilers()
{
foreach (var profiler in systemProfilers.Values)
{
profiler.Reset();
}
}
/// <summary>
/// 获取系统性能数据
/// </summary>
public Dictionary<string, (float averageTime, float maxTime, int sampleCount)> GetSystemProfilingData()
{
var result = new Dictionary<string, (float, float, int)>();
foreach (var kvp in systemProfilers)
{
var profiler = kvp.Value;
result[kvp.Key] = (profiler.AverageTime, profiler.maxTime, profiler.sampleCount);
}
return result;
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 6cc8ba26ea081f143bce9da130c6992a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: