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

  

posted @   D个人笔记  阅读(159)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示