Add: First pass optimization
This commit is contained in:
@@ -1,55 +1,40 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OctoCore.UI
|
||||
{
|
||||
public class PerformanceOverlay : MonoBehaviour
|
||||
{
|
||||
#region Constants and Static Fields
|
||||
|
||||
public static PerformanceOverlay Instance { get; private set; }
|
||||
|
||||
private const string GREEN = "<color=#00ff88>", YELLOW = "<color=#ffcc00>", RED = "<color=#ff4444>", END = "</color>";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Serialized Fields
|
||||
private const string GREEN = "<color=#00ff88>";
|
||||
private const string YELLOW = "<color=#ffcc00>";
|
||||
private const string ORANGE = "<color=#ff8800>";
|
||||
private const string RED_ORANGE = "<color=#ff4400>";
|
||||
private const string RED = "<color=#ff0000>";
|
||||
private const string END = "</color>";
|
||||
|
||||
[Header("UI Reference")]
|
||||
[SerializeField] private Text _displayText;
|
||||
|
||||
[Header("FPS Settings")]
|
||||
[Tooltip("Number of frames to average for a smooth reading.")]
|
||||
[SerializeField] private int _sampleSize = 60;
|
||||
|
||||
[Tooltip("EMA smoothing factor (0.01 = very smooth, 0.1 = reactive)")]
|
||||
[SerializeField, Range(0.01f, 0.2f)] private float _smoothing = 0.05f;
|
||||
[Tooltip("How often, in seconds, the display refreshes.")]
|
||||
[SerializeField] private float _updateInterval = 0.1f;
|
||||
|
||||
[Header("Thresholds")]
|
||||
[SerializeField] private int _goodFps = 60;
|
||||
[SerializeField] private int _warningFps = 30;
|
||||
[SerializeField] private int _greenFps = 59;
|
||||
[SerializeField] private int _yellowFps = 50;
|
||||
[SerializeField] private int _orangeFps = 40;
|
||||
[SerializeField] private int _redOrangeFps = 30;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Instance Fields
|
||||
|
||||
private readonly Queue<float> _frameTimes = new Queue<float>();
|
||||
private float _accumulatedTime;
|
||||
private float _smoothedFrameTime;
|
||||
private float _timeSinceLastUpdate;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Unity Lifecycle Methods
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
|
||||
@@ -57,26 +42,24 @@ namespace OctoCore.UI
|
||||
_displayText = GetComponent<Text>();
|
||||
|
||||
ConfigureText();
|
||||
_smoothedFrameTime = 1f / 60f;
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
_sampleSize = Mathf.Max(1, _sampleSize);
|
||||
_updateInterval = Mathf.Max(0.02f, _updateInterval);
|
||||
_greenFps = Mathf.Max(_yellowFps + 1, _greenFps);
|
||||
_yellowFps = Mathf.Max(_orangeFps + 1, _yellowFps);
|
||||
_orangeFps = Mathf.Max(_redOrangeFps + 1, _orangeFps);
|
||||
_redOrangeFps = Mathf.Max(1, _redOrangeFps);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
float deltaTime = Time.unscaledDeltaTime;
|
||||
|
||||
_frameTimes.Enqueue(deltaTime);
|
||||
_accumulatedTime += deltaTime;
|
||||
|
||||
if (_frameTimes.Count > _sampleSize)
|
||||
_accumulatedTime -= _frameTimes.Dequeue();
|
||||
|
||||
_timeSinceLastUpdate += deltaTime;
|
||||
float dt = Time.unscaledDeltaTime;
|
||||
_smoothedFrameTime += (dt - _smoothedFrameTime) * _smoothing;
|
||||
|
||||
_timeSinceLastUpdate += dt;
|
||||
if (_timeSinceLastUpdate >= _updateInterval)
|
||||
{
|
||||
_timeSinceLastUpdate = 0f;
|
||||
@@ -84,14 +67,9 @@ namespace OctoCore.UI
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private void ConfigureText()
|
||||
{
|
||||
if (_displayText == null) return;
|
||||
|
||||
_displayText.supportRichText = true;
|
||||
_displayText.horizontalOverflow = HorizontalWrapMode.Overflow;
|
||||
_displayText.verticalOverflow = VerticalWrapMode.Overflow;
|
||||
@@ -100,23 +78,18 @@ namespace OctoCore.UI
|
||||
|
||||
private void RefreshDisplay()
|
||||
{
|
||||
if (_displayText == null) return;
|
||||
if (_frameTimes.Count == 0) return;
|
||||
if (_displayText == null || _smoothedFrameTime <= 0f) return;
|
||||
|
||||
float avgFrameTime = _accumulatedTime / _frameTimes.Count;
|
||||
if (avgFrameTime <= 0f) return;
|
||||
float fps = 1f / _smoothedFrameTime;
|
||||
float frameTimeMs = _smoothedFrameTime * 1000f;
|
||||
|
||||
float fps = 1f / avgFrameTime;
|
||||
float frameTimeMs = avgFrameTime * 1000f;
|
||||
string colour = fps >= _greenFps ? GREEN
|
||||
: fps >= _yellowFps ? YELLOW
|
||||
: fps >= _orangeFps ? ORANGE
|
||||
: fps >= _redOrangeFps ? RED_ORANGE
|
||||
: RED;
|
||||
|
||||
string fpsColour = fps >= _goodFps ? GREEN
|
||||
: fps >= _warningFps ? YELLOW
|
||||
: RED;
|
||||
|
||||
_displayText.text =
|
||||
$"{fpsColour}{fps:F0} FPS{END}\n" +
|
||||
$"Frame {frameTimeMs:F2} ms";
|
||||
_displayText.text = $"{colour}{fps:F0} FPS{END}\n{frameTimeMs:F1} ms";
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user