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 保存方法:

  

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 内

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 @ 2022-08-10 16:53  D个人笔记  阅读(146)  评论(0编辑  收藏  举报