Files
aibis-dream/Assets/Scripts/Utility/PerformanceOptimizer.cs
T
2025-09-01 21:25:54 +08:00

193 lines
6.8 KiB
C#

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);
}
}
}