From 08755ce2cdf9e61b1479fa6fe96597c6ecec47bf Mon Sep 17 00:00:00 2001 From: Jahnisse Date: Wed, 3 Jun 2026 16:38:20 +0200 Subject: [PATCH] Fix : Uncapped FPS ; Removed : Estimated Input lag --- .../Scripts/Core/Utils/PerformanceOverlay.cs | 66 ++++++++++--------- 1 file changed, 34 insertions(+), 32 deletions(-) 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