diff --git a/Assets/_Content/Scripts/Core/Utils/PerformanceOverlay.cs b/Assets/_Content/Scripts/Core/Utils/PerformanceOverlay.cs
index 079a712f..e6e85584 100644
--- a/Assets/_Content/Scripts/Core/Utils/PerformanceOverlay.cs
+++ b/Assets/_Content/Scripts/Core/Utils/PerformanceOverlay.cs
@@ -4,21 +4,13 @@ using System.Collections.Generic;
namespace OctoCore.UI
{
- ///
- /// Displays FPS, frame time, and estimated input lag.
- /// Singleton that persists across scene loads. Safe to place in every scene — duplicates are destroyed automatically.
- /// Requires a Canvas Text component assigned in the Inspector.
- ///
public class PerformanceOverlay : MonoBehaviour
{
#region Constants and Static Fields
public static PerformanceOverlay Instance { get; private set; }
- private const string GREEN = "";
- private const string YELLOW = "";
- private const string RED = "";
- private const string END = "";
+ private const string GREEN = "", YELLOW = "", RED = "", END = "";
#endregion
@@ -31,13 +23,9 @@ namespace OctoCore.UI
[Tooltip("Number of frames to average for a smooth reading.")]
[SerializeField] private int _sampleSize = 60;
- [Tooltip("How often (seconds) the display refreshes.")]
+ [Tooltip("How often, in seconds, the display refreshes.")]
[SerializeField] private float _updateInterval = 0.1f;
- [Header("Input Lag Settings")]
- [Tooltip("Render pipeline latency in frames. 1 for Built-in/URP, 2 for HDRP.")]
- [SerializeField] private int _pipelineLatencyFrames = 1;
-
[Header("Thresholds")]
[SerializeField] private int _goodFps = 60;
[SerializeField] private int _warningFps = 30;
@@ -64,18 +52,31 @@ namespace OctoCore.UI
Instance = this;
DontDestroyOnLoad(gameObject);
+
+ if (_displayText == null)
+ _displayText = GetComponent();
+
+ ConfigureText();
+ }
+
+ private void OnValidate()
+ {
+ _sampleSize = Mathf.Max(1, _sampleSize);
+ _updateInterval = Mathf.Max(0.02f, _updateInterval);
}
private void Update()
{
- float dt = Time.unscaledDeltaTime;
+ float deltaTime = Time.unscaledDeltaTime;
+
+ _frameTimes.Enqueue(deltaTime);
+ _accumulatedTime += deltaTime;
- _frameTimes.Enqueue(dt);
- _accumulatedTime += dt;
if (_frameTimes.Count > _sampleSize)
_accumulatedTime -= _frameTimes.Dequeue();
- _timeSinceLastUpdate += dt;
+ _timeSinceLastUpdate += deltaTime;
+
if (_timeSinceLastUpdate >= _updateInterval)
{
_timeSinceLastUpdate = 0f;
@@ -85,36 +86,37 @@ namespace OctoCore.UI
#endregion
- #region Public Methods
-
- /// Toggles the overlay on / off.
- public void Toggle() => _displayText.gameObject.SetActive(!_displayText.gameObject.activeSelf);
-
- #endregion
-
#region Private Methods
+ private void ConfigureText()
+ {
+ if (_displayText == null) return;
+
+ _displayText.supportRichText = true;
+ _displayText.horizontalOverflow = HorizontalWrapMode.Overflow;
+ _displayText.verticalOverflow = VerticalWrapMode.Overflow;
+ _displayText.alignment = TextAnchor.UpperLeft;
+ }
+
private void RefreshDisplay()
{
if (_displayText == null) return;
+ if (_frameTimes.Count == 0) return;
float avgFrameTime = _accumulatedTime / _frameTimes.Count;
+ if (avgFrameTime <= 0f) return;
+
float fps = 1f / avgFrameTime;
float frameTimeMs = avgFrameTime * 1000f;
- // HID polling floor (~8 ms for 125 Hz USB; ~1 ms for 1000 Hz)
- float inputLagMs = frameTimeMs * (1 + _pipelineLatencyFrames) + 8f;
-
string fpsColour = fps >= _goodFps ? GREEN
: fps >= _warningFps ? YELLOW
: RED;
_displayText.text =
- $"{fpsColour}{fps,5:F0} FPS{END}\n" +
- $"Frame {frameTimeMs,6:F2} ms\n" +
- $"Lag ≈ {inputLagMs,6:F2} ms";
+ $"{fpsColour}{fps:F0} FPS{END}\n" +
+ $"Frame {frameTimeMs:F2} ms";
}
-
#endregion
}
}
\ No newline at end of file