Add: First pass optimization

This commit is contained in:
Jahnisse
2026-06-11 17:10:20 +02:00
parent 8355775ff4
commit 7e9e358c8e
74 changed files with 5352 additions and 1417 deletions
@@ -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
}
}