Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I zoom out on the CPU profiler window?

Discussion in 'Editor & General Support' started by clintonb, Apr 5, 2019.

  1. clintonb

    clintonb

    Joined:
    Dec 14, 2013
    Posts:
    15
    When I look at the CPU profiler, showing my game built with Unity 2018.1.6f1 running on device, I see something like this:

    upload_2019-4-5_11-34-55.png

    Clearly, I'm often running slower than 15 fps. But, I can't tell how bad it gets -- 3/4 of the way through, am I spiking and getting really bad performance, or is it just marginally worse?

    Is there some way to zoom out this window, or change it so it isn't scaled to only showing 66 ms or time each frame?
     
  2. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,431
    Sadly there is no way to do this right now, it is on our backlog of UX improvements though. As a workaround for now, you can click on the colored boxes in the legend of the chart to hide categories, e.g. "others" so that you have more space for the rest and maybe more relevant metrics.

    BTW, Other, in this case seems quite high as you're profiling the Editor that still needs to render around the game running within it. It is recommended to profile on your target platform to find issues and only profile within the editor for more rapid iteration times during optimization.
     
    KarlKarl2000 likes this.
  3. Ni2Be

    Ni2Be

    Joined:
    Nov 10, 2017
    Posts:
    6

    Is there still no way to zoom out? (2021.1.4f1)

    btw it's an awesome tool :D
    Is there an article or talk on how it works?
     
  4. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,431
    Sadly no, other more pressing concerns had to be addressed before hand, like making the Profiler Window Extendable from C# (landed in 2021.2) which will eventually also include ways to specify the chart drawing in more detail or entirely overriding it and in that push we'll likely be revisiting the chart UX. Right now the major focus lies on the Memory Profiler though.

    Like something on the inner workings? Not really, the Profiler Documentation tries to cover everything that's outward facing and hints a bit at the underlying basis...
     
  5. MaDDoX

    MaDDoX

    Joined:
    Nov 10, 2009
    Posts:
    764
    It's probably a bug or something, but if you go to the panel settings (3 dots button at the top-right corner) and enable color-blind mode, it'll resize to fit. You may disable the option after that.
     
    Ravarion likes this.
  6. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Gosh it sure would be nice to have that zoom out of the profiler spikes.... or ya know... for it to automatically resize itself based on the highest spikes? Even a 2x height option would suffice temporarily? Heres a shot of Unity 2021.1.22f1



    I get that this isn't a huge priority, but man guys - its been years! Years I tell you! Sure would be more intuitive then comparing the frame times to get an idea of the top and bottom of performance.

    The above suggestion to hit color-blind mode doesn't work here.
     
    OberZine and Riptide559 like this.
  7. lukasleder

    lukasleder

    Joined:
    Sep 7, 2017
    Posts:
    16
    Hello, needed this for some tests in the project and made a small script that might help somebody implement it for themselves.

    Three things to note:
    - This is very hacky, because everything is internal and has to be fetched with reflections
    - I didn't look into how exactly the variables i change here affect the chart, if you want to look into it, take a look into unity's chart class
    - This only works when not recording (so when the profiler is not updating itself)

    Anyway, here is the code, it's not cleaned up but it has the basic idea in it


    Code (CSharp):
    1. using System;
    2. using System.Reflection;
    3. using UnityEditor;
    4.  
    5. namespace _Project.Code.Scripts
    6. {
    7.     using UnityEngine;
    8.  
    9.     namespace UnityEditor
    10.     {
    11.         public class ProfilerWindowAccess : EditorWindow
    12.         {
    13.             private float zoom = 1.0f;
    14.             private float previousZoom = 1.0f;
    15.  
    16.             private object chart;
    17.             private FieldInfo dataScaleField;
    18.             private FieldInfo maximumScaleInterpolationValueField;
    19.  
    20.             private object cpuProfilerModule;
    21.             private MethodInfo updateChartMethod;
    22.  
    23.             private EditorWindow profilerWindow;
    24.  
    25.             [MenuItem("Window/Profiler Window Access Test")]
    26.             public static void ShowWindow()
    27.             {
    28.                 GetWindow<ProfilerWindowAccess>("Profiler Window Access Test");
    29.             }
    30.  
    31.             private void OnEnable()
    32.             {
    33.                 // Cache the Profiler window and the CPU Profiler module
    34.                 CacheProfiler();
    35.             }
    36.  
    37.             private void OnGUI()
    38.             {
    39.                 // Draw a basic window with a slider for zoom and a button to reset the zoom
    40.                 GUILayout.Label("Profiler Window Access Test", EditorStyles.boldLabel);
    41.                 GUILayout.Label("This window is used to test accessing the Profiler window using reflection.");
    42.  
    43.                 // These are just some arbitrary values I chose for the slider
    44.                 zoom = EditorGUILayout.Slider("Zoom", zoom, 0.0001f, 0.2f);
    45.  
    46.                 if (GUILayout.Button("Reset Zoom"))
    47.                 {
    48.                     zoom = 0.1f;
    49.                 }
    50.  
    51.                 if (Math.Abs(zoom - previousZoom) > Mathf.Epsilon)
    52.                 {
    53.                     previousZoom = zoom;
    54.                     UpdateScaleValue();
    55.                 }
    56.             }
    57.  
    58.             private void UpdateScaleValue()
    59.             {
    60.                 // Note: I'm not fully sure how the chart's m_DataScale and m_MaximumScaleInterpolationValue properties work, but they seem to be related to the zoom level of the chart somehow.
    61.                 // I didn't do any further research on this, but I'm sure somebody has some time to look into this :D as it is now is enough for my usecase.
    62.  
    63.                 // Setting the chart's m_DataScale property
    64.                 dataScaleField.SetValue(chart, zoom);
    65.  
    66.                 // Setting the chart's m_MaximumScaleInterpolationValue property
    67.                 maximumScaleInterpolationValueField.SetValue(chart, zoom);
    68.  
    69.                 //Call UpdateChart of the ProfilerModuleBase (the base class of the CPU Profiler module)
    70.                 updateChartMethod.Invoke(cpuProfilerModule, new object[] { });
    71.  
    72.                 // Refresh the Profiler window
    73.                 profilerWindow.Repaint();
    74.             }
    75.  
    76.             private void CacheProfiler()
    77.             {
    78.                 BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
    79.  
    80.                 // Get a reference to the Unity Profiler window using reflection because it is internal
    81.                 Assembly assembly = Assembly.GetAssembly(typeof(EditorWindow));
    82.                 System.Type profilerWindowType = assembly.GetType("UnityEditor.ProfilerWindow");
    83.                 profilerWindow = EditorWindow.GetWindow(profilerWindowType);
    84.  
    85.                 // Get a reference to the CPU Profiler module in the Profiler window using reflection, because it is internal
    86.                 System.Type cpuProfilerModuleType = assembly.GetType("UnityEditorInternal.Profiling.CPUProfilerModule");
    87.                 FieldInfo cpuProfilerModuleProperty = profilerWindowType.GetField("m_Modules", bindFlags);
    88.                 object moduleList = cpuProfilerModuleProperty.GetValue(profilerWindow);
    89.                 System.Type moduleArrayType = moduleList.GetType();
    90.  
    91.                 // moduleList is a ProfilerModule list, but we can't cast it to List<ProfilerModule> because it's an internal type
    92.                 // So we have to use reflection to get the list length and get the elements one by one
    93.                 MethodInfo getCountMethod = moduleArrayType.GetMethod("get_Count", bindFlags);
    94.                 int count = (int)getCountMethod.Invoke(moduleList, null);
    95.                 MethodInfo getItemMethod = moduleArrayType.GetMethod("get_Item", bindFlags);
    96.  
    97.                 // The CPU Profiler module is the first ProfilerModule in the list, but i just loop through the list to be sure
    98.                 cpuProfilerModule = null;
    99.                 for (int i = 0; i < count; i++)
    100.                 {
    101.                     object module = getItemMethod.Invoke(moduleList, new object[] { i });
    102.                     if (module.GetType() == cpuProfilerModuleType)
    103.                     {
    104.                         cpuProfilerModule = module;
    105.                         break;
    106.                     }
    107.                 }
    108.  
    109.                 // Getting the chart property
    110.                 FieldInfo chartField = cpuProfilerModuleType.GetField("m_Chart", bindFlags);
    111.                 chart = chartField.GetValue(cpuProfilerModule);
    112.  
    113.                 // Getting the chart's m_DataScale property
    114.                 System.Type chartType = assembly.GetType("UnityEditorInternal.ProfilerChart");
    115.                 dataScaleField = chartType.GetField("m_DataScale", bindFlags);
    116.  
    117.                 // Getting the chart's m_MaximumScaleInterpolationValue property
    118.                 maximumScaleInterpolationValueField = chartType.GetField("m_MaximumScaleInterpolationValue", bindFlags);
    119.  
    120.                 //Call UpdateChart of the ProfilerModuleBase class
    121.                 System.Type profilerModuleBaseType = assembly.GetType("UnityEditorInternal.Profiling.ProfilerModuleBase");
    122.                 updateChartMethod = profilerModuleBaseType.GetMethod("UpdateChart", bindFlags);
    123.             }
    124.         }
    125.     }
    126. }
     
    Hazzardt likes this.