Unity 性能分析小工具
下文有两个方法,分别是一段检测执行过程耗费时间的代码,还有一个是保存和加载Unity Profiler 的代码(因为UnityProfiler 只能显示一部分的数据,如果运行时间长的话有部分分析数据查看不到)
1. 检测执行耗费时间 代码如下:
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using UnityEngine; public class CustomTimer : IDisposable { private string m_timerName; private int m_numTests; private Stopwatch m_watch; public CustomTimer(string timerName,int numTests) { m_timerName = timerName; m_numTests = numTests; if (m_numTests <= 0) m_numTests = 1; m_watch = Stopwatch.StartNew(); } public void Dispose() { m_watch.Stop(); float ms = m_watch.ElapsedMilliseconds; UnityEngine.Debug.Log(string.Format("{0} finished: {1:0.00}ms total , {2:0.00000}ms per test for {3} tests", m_timerName, ms, ms / m_numTests, m_numTests)); } }
使用方法如下: 在程序块里放入自己要检测的代码,在循环使用的时候,把0改成循环的次数就可以了
using (new CustomTimer("My Test", 0)) { using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)) { yield return request.SendWebRequest(); if (request.isHttpError || request.isNetworkError) { // 下载出错 print(request.error); } else { // 下载完成 AssetBundle assetBundle = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; GameObject obj = assetBundle.LoadAsset<GameObject>(assetBundle.GetAllAssetNames()[0]); GameObject obj2 = GameObject.Instantiate(obj); this.obj = obj2.transform; // 优先释放request 会降低内存峰值 request.Dispose(); } } }
2. Unity Profiler 保存方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Profiling; public class ProfilerDataSaverComponent : MonoBehaviour { int _count = 0; void Start() { Profiler.logFile = "" ; } // Update is called once per frame void Update() { if (Input.GetKey(KeyCode.LeftControl)&& Input.GetKeyDown(KeyCode.H)) { StartCoroutine(SaveProfilerData()); } } IEnumerator SaveProfilerData() { while ( true ) { string filepath = Application.persistentDataPath + "/profilerLog" + _count; Profiler.logFile = filepath; Profiler.enableBinaryLog = true ; Profiler.enabled = true ; for ( int i = 0; i < 300; i++) { yield return new WaitForEndOfFrame(); if (!Profiler.enabled) { Profiler.enabled = true ; } } _count++; } } } |
读取保存的UnityProfiler数据: 在Window/ProfilerDataLoader 内
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | using System.Collections; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using UnityEditor; using UnityEngine; using UnityEngine.Profiling; public class ProfilerDataLoaderWindow : EditorWindow { static List< string > s_cachedFilePaths; static int s_chosenIndex = -1; [MenuItem( "Window/ProfilerDataLoader" )] static void Init() { ProfilerDataLoaderWindow window = (ProfilerDataLoaderWindow)EditorWindow.GetWindow( typeof (ProfilerDataLoaderWindow)); } static void ReadProfilerDataFiles() { Profiler.logFile = "" ; string [] filePath = Directory.GetFiles(Application.persistentDataPath , "ProfilerLog*" ); s_cachedFilePaths = new List< string >(); Regex test = new Regex( ".data$" ); for ( int i = 0; i < filePath.Length; i++) { string thisPath = filePath[i]; Match match = test.Match(thisPath); if (!match.Success) { Debug.Log( "Found file: " + thisPath); s_cachedFilePaths.Add(thisPath); } } s_chosenIndex = -1; } private void OnGUI() { if (GUILayout.Button( "Find Files" )) { ReadProfilerDataFiles(); } if (s_cachedFilePaths == null ) return ; EditorGUILayout.Space(); EditorGUILayout.LabelField( "Files" ); EditorGUILayout.BeginHorizontal(); GUIStyle defaultStyle = new GUIStyle(GUI.skin.button); defaultStyle.fixedWidth = 40; GUIStyle highlightedStyle = new GUIStyle(defaultStyle); highlightedStyle.normal.textColor = Color.red; for ( int i = 0; i < s_cachedFilePaths.Count; i++) { if (i%5==0) { EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); } GUIStyle thisStyle = null ; if (s_chosenIndex ==i) { thisStyle = highlightedStyle; } else { thisStyle = defaultStyle; } if (GUILayout.Button( "" + i, thisStyle)) { Profiler.AddFramesFromFile(s_cachedFilePaths[i]); s_chosenIndex = i; } } EditorGUILayout.EndHorizontal(); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】