void Update() { Init(); FrameTimingManager.CaptureFrameTimings(); _sampledFrames = FrameTimingManager.GetLatestTimings(1, timing); _times.Add(timing[0]); while (_times.Count > NUM_FRAMES) { _times.RemoveAt(0); } double avgCpuFrameTime = 0f; double avgGpuFrameTime = 0f; _targetFrameTime = (1f / Application.targetFrameRate) * 1000; foreach (var t in _times) { avgCpuFrameTime += t.cpuFrameTime; avgGpuFrameTime += t.gpuFrameTime; } avgCpuFrameTime /= NUM_FRAMES; avgGpuFrameTime /= NUM_FRAMES; // Assing to array entryDefinitions[0].Value = _targetFrameTime; entryDefinitions[1].Value = avgCpuFrameTime; entryDefinitions[2].Value = avgGpuFrameTime; entryDefinitions[3].Value = 1000f / Mathf.Max(Mathf.Max((float)_targetFrameTime, (float)avgCpuFrameTime), (float)avgGpuFrameTime); }
/// <summary> /// Update timing data from profiling counters. /// </summary> public void UpdateFrameTiming() { m_Timing[0] = default; m_Sample = default; FrameTimingManager.CaptureFrameTimings(); FrameTimingManager.GetLatestTimings(1, m_Timing); if (m_Timing.Length > 0) { m_Sample.FullFrameTime = (float)m_Timing.First().cpuFrameTime; m_Sample.FramesPerSecond = m_Sample.FullFrameTime > 0f ? 1000f / m_Sample.FullFrameTime : 0f; m_Sample.MainThreadCPUFrameTime = (float)m_Timing.First().cpuMainThreadFrameTime; m_Sample.MainThreadCPUPresentWaitTime = (float)m_Timing.First().cpuMainThreadPresentWaitTime; m_Sample.RenderThreadCPUFrameTime = (float)m_Timing.First().cpuRenderThreadFrameTime; m_Sample.GPUFrameTime = (float)m_Timing.First().gpuFrameTime; } m_FrameHistory.DiscardOldSamples(sampleHistorySize); m_FrameHistory.Add(m_Sample); m_FrameHistory.ComputeAggregateValues(); m_BottleneckHistory.DiscardOldSamples(bottleneckHistorySize); m_BottleneckHistory.AddBottleneckFromAveragedSample(m_FrameHistory.SampleAverage); m_BottleneckHistory.ComputeHistogram(); }
protected override void OnUpdate(float deltaTime) { if (Debug.isDebugBuild) { FrameTimingManager.CaptureFrameTimings(); FrameTimingManager.GetLatestTimings((uint)mFrameTimings.Length, mFrameTimings); } }
// Update is called once per frame void Update() { // var frameTimings_ = new FrameTiming[1]; FrameTimingManager.CaptureFrameTimings(); uint numReturened = FrameTimingManager.GetLatestTimings(1, frameTimings_); // _text.ft = frameTimings[0]; if (numReturened > 0) { var ft = frameTimings_[0]; text_.ft = ft; // GPU負荷をみて解像度を変更する // UNITY社サンプルでは FrameTimingManager.GetCpuTimerFrequency() が取れない端末がある // ネイティブプラグインなどからクロックをとれると思うが deltaTimeかcpuFrameTimeあたりと比較すれば良いかもしれない // 今はCPU負荷が高いので固定値にしている if (ft.gpuFrameTime > 0.2) // if (ft.gpuFrameTime/ft.cpuFrameTime > 0.5) { ChangeResolution(ft.heightScale * 0.8f); // _screenScale.Val *= 0.9f; } else { ChangeResolution(ft.heightScale * 1.2f); // _screenScale.Val *= 1.1f; } /* * if (Math.Abs(ft.gpuFrameTime) > DOUBLE_EPSILON) * { * * var diff = ft.cpuTimeFrameComplete - ft.cpuTimePresentCalled; * var latencyms = diff * 1000.0 / FrameTimingManager.GetCpuTimerFrequency(); * double latencyFrames = latencyms / ft.gpuFrameTime; * * Debug.Log( "cpuTime" + FrameTimingManager.GetCpuTimerFrequency() + " latencyms" + latencyms + " gpuFrame=" + ft.gpuFrameTime + " latency=" + latencyFrames); * * if (latencyFrames > 2.0) * { // GPU Bound * _screenScale.value *= 0.9f; * } * if (latencyFrames < 1.0) * { // in * _screenScale.value *= 1.1f; * } * } */ } }
// Update is called once per frame void Update() { ++frameCount; if (frameCount <= 2) { return; } FrameTimingManager.CaptureFrameTimings(); var n = FrameTimingManager.GetLatestTimings(2, frameTimings); if (n < 1) { //return; } if (uiText != null) { int width = (int)Mathf.Ceil(ScalableBufferManager.widthScaleFactor * Screen.currentResolution.width); int height = (int)Mathf.Ceil(ScalableBufferManager.heightScaleFactor * Screen.currentResolution.height); uiText.text = string.Format( "Scale: {0:F3} x {1:F3}\n" + "Resolution: {2} x {3}\n" + "cpuFrameTime: {4:F6}\n" + "gpuFrameTime: {5:F6}\n" + "cpuTimePresentCalled: {6}\n" + "cpuTimeFrameComplete: {7}\n" + "Dynamic Scale: {8:F3} x {9:F3}\n" + "syncInterval: {10}\n" + "GetCpuTimerFrequency: {11}\n" + "GetGpuTimerFrequency: {12}\n" + "GetVSyncsPerSecond: {13}" , ScalableBufferManager.widthScaleFactor, ScalableBufferManager.heightScaleFactor, width, height, frameTimings[0].cpuFrameTime, frameTimings[0].gpuFrameTime, frameTimings[0].cpuTimePresentCalled, frameTimings[0].cpuTimeFrameComplete, frameTimings[0].widthScale, frameTimings[0].heightScale, frameTimings[0].syncInterval, FrameTimingManager.GetCpuTimerFrequency(), FrameTimingManager.GetGpuTimerFrequency(), FrameTimingManager.GetVSyncsPerSecond() ); } }
// Estimate the next frame time and update the resolution scale if necessary. private void DetermineResolution() { ++m_frameCount; if (m_frameCount <= kNumFrameTimings) { return; } FrameTimingManager.CaptureFrameTimings(); FrameTimingManager.GetLatestTimings(kNumFrameTimings, frameTimings); if (frameTimings.Length < kNumFrameTimings) { Debug.LogFormat("Skipping frame {0}, didn't get enough frame timings.", m_frameCount); return; } m_gpuFrameTime = (double)frameTimings[0].gpuFrameTime; m_cpuFrameTime = (double)frameTimings[0].cpuFrameTime; }
public static int GetLatestTimings_s(IntPtr l) { int result; try { uint numFrames; LuaObject.checkType(l, 1, out numFrames); FrameTiming[] timings; LuaObject.checkArray <FrameTiming>(l, 2, out timings); uint latestTimings = FrameTimingManager.GetLatestTimings(numFrames, timings); LuaObject.pushValue(l, true); LuaObject.pushValue(l, latestTimings); result = 2; } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
private void Update() { // フレーム情報をキャプチャする FrameTimingManager.CaptureFrameTimings(); // 必要なフレーム数分の情報を取得する // 戻り値は実際に取得できたフレーム情報の数 var numFrames = FrameTimingManager.GetLatestTimings((uint)_frameTimings.Length, _frameTimings); if (numFrames == 0) // 2020.02.16修正しました { // 1フレームの情報も得られていない場合はスキップ return; } // CPUの処理時間、CPUの処理時間を格納 CpuFrameTime = (float)(_frameTimings[0].cpuFrameTime * 1000); GpuFrameTime = (float)(_frameTimings[0].gpuFrameTime * 1000); text.text = string.Format($"CPU = {CpuFrameTime},GPU={GpuFrameTime}"); }
private void Update() { dtBuffer[cnt] = Time.unscaledDeltaTime; dtParS = dtBuffer.Average(); //gpuBuffer cnt++; if (cnt >= 60) { cnt = 0; fps = 1f / dtParS; } //メモリ更新 meter.localScale = new Vector3(dtParS * 60f, 1); // フレーム情報をキャプチャする FrameTimingManager.CaptureFrameTimings(); // 必要なフレーム数分の情報を取得する // 戻り値は実際に取得できたフレーム情報の数 var numFrames = FrameTimingManager.GetLatestTimings((uint)_frameTimings.Length, _frameTimings); if (numFrames == 0) // 2020.02.16修正しました { // 1フレームの情報も得られていない場合はスキップ return; } // CPUの処理時間、CPUの処理時間を格納 CpuFrameTime = (float)(_frameTimings[0].cpuFrameTime); GpuFrameTime = (float)(_frameTimings[0].gpuFrameTime); gpuBuffer[gCnt] = (float)(_frameTimings[0].gpuFrameTime); gCnt++; if (gCnt >= 60) { gCnt = 0; gpuParS = gpuBuffer.Average(); } }
private void LateUpdate() { if (window == null) { return; } // Update window transformation. Transform cameraTransform = CameraCache.Main ? CameraCache.Main.transform : null; if (isVisible && cameraTransform != null) { float t = Time.deltaTime * windowFollowSpeed; window.position = Vector3.Lerp(window.position, CalculateWindowPosition(cameraTransform), t); window.rotation = Quaternion.Slerp(window.rotation, CalculateWindowRotation(cameraTransform), t); window.localScale = defaultWindowScale * windowScale; CalculateBackgroundSize(); } // Capture frame timings every frame and read from it depending on the frameSampleRate. FrameTimingManager.CaptureFrameTimings(); ++frameCount; float elapsedSeconds = stopwatch.ElapsedMilliseconds * 0.001f; if (elapsedSeconds >= frameSampleRate) { int cpuFrameRate = (int)(1.0f / (elapsedSeconds / frameCount)); int gpuFrameRate = 0; // Many platforms do not yet support the FrameTimingManager. When timing data is returned from the FrameTimingManager we will use // its timing data, else we will depend on the stopwatch. uint frameTimingsCount = FrameTimingManager.GetLatestTimings((uint)Mathf.Min(frameCount, maxFrameTimings), frameTimings); if (frameTimingsCount != 0) { float cpuFrameTime, gpuFrameTime; AverageFrameTiming(frameTimings, frameTimingsCount, out cpuFrameTime, out gpuFrameTime); cpuFrameRate = (int)(1.0f / (cpuFrameTime / frameCount)); gpuFrameRate = (int)(1.0f / (gpuFrameTime / frameCount)); } // Update frame rate text. cpuFrameRateText.text = cpuFrameRateStrings[Mathf.Clamp(cpuFrameRate, 0, maxTargetFrameRate)]; if (gpuFrameRate != 0) { gpuFrameRateText.gameObject.SetActive(true); gpuFrameRateText.text = gpuFrameRateStrings[Mathf.Clamp(gpuFrameRate, 0, maxTargetFrameRate)]; } // Update frame colors. if (frameInfoVisible) { for (int i = frameRange - 1; i > 0; --i) { frameInfoColors[i] = frameInfoColors[i - 1]; } frameInfoColors[0] = CalculateFrameColor(cpuFrameRate); frameInfoPropertyBlock.SetVectorArray(colorID, frameInfoColors); } // Reset timers. frameCount = 0; stopwatch.Reset(); stopwatch.Start(); } // Draw frame info. if (isVisible && frameInfoVisible) { Matrix4x4 parentLocalToWorldMatrix = window.localToWorldMatrix; if (defaultInstancedMaterial != null) { frameInfoPropertyBlock.SetMatrix(parentMatrixID, parentLocalToWorldMatrix); Graphics.DrawMeshInstanced(quadMesh, 0, defaultInstancedMaterial, frameInfoMatrices, frameInfoMatrices.Length, frameInfoPropertyBlock, UnityEngine.Rendering.ShadowCastingMode.Off, false); } else { // If a instanced material is not available, fall back to non-instanced rendering. for (int i = 0; i < frameInfoMatrices.Length; ++i) { frameInfoPropertyBlock.SetColor(colorID, frameInfoColors[i]); Graphics.DrawMesh(quadMesh, parentLocalToWorldMatrix * frameInfoMatrices[i], defaultMaterial, 0, null, 0, frameInfoPropertyBlock, false, false, false); } } } // Update memory statistics. if (isVisible && memoryStatsVisible) { ulong limit = AppMemoryUsageLimit; if (limit != limitMemoryUsage) { if (WillDisplayedMemoryUsageDiffer(limitMemoryUsage, limit, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, limitMemoryText, limitMemoryString, limit); } limitMemoryUsage = limit; } ulong usage = AppMemoryUsage; if (usage != memoryUsage) { usedAnchor.localScale = new Vector3((float)usage / limitMemoryUsage, usedAnchor.localScale.y, usedAnchor.localScale.z); if (WillDisplayedMemoryUsageDiffer(memoryUsage, usage, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, usedMemoryText, usedMemoryString, usage); } memoryUsage = usage; } if (memoryUsage > peakMemoryUsage) { peakAnchor.localScale = new Vector3((float)memoryUsage / limitMemoryUsage, peakAnchor.localScale.y, peakAnchor.localScale.z); if (WillDisplayedMemoryUsageDiffer(peakMemoryUsage, memoryUsage, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, peakMemoryText, peakMemoryString, memoryUsage); } peakMemoryUsage = memoryUsage; } } // Update visibility state. window.gameObject.SetActive(isVisible); memoryStats.gameObject.SetActive(memoryStatsVisible); }
private void LateUpdate() { if (window == null) { return; } // Update window transformation. if (window.activeSelf && mainCamera != null) { float t = Time.deltaTime * windowFollowSpeed; window.transform.position = Vector3.Lerp(window.transform.position, CalculateWindowPosition(mainCamera.transform), t); window.transform.rotation = Quaternion.Slerp(window.transform.rotation, CalculateWindowRotation(mainCamera.transform), t); window.transform.localScale = defaultWindowScale * windowScale; } // Capture frame timings every frame and read from it depending on the frameSampleRate. FrameTimingManager.CaptureFrameTimings(); ++frameCount; float elapsedSeconds = stopwatch.ElapsedMilliseconds * 0.001f; if (elapsedSeconds >= frameSampleRate) { int cpuFrameRate = (int)(1.0f / (elapsedSeconds / frameCount)); int gpuFrameRate = 0; // Many platforms do not yet support the FrameTimingManager. When timing data is returned from the FrameTimingManager we will use // its timing data, else we will depend on the stopwatch. uint frameTimingsCount = FrameTimingManager.GetLatestTimings((uint)Mathf.Min(frameCount, maxFrameTimings), frameTimings); if (frameTimingsCount != 0) { float cpuFrameTime, gpuFrameTime; AverageFrameTiming(frameTimings, frameTimingsCount, out cpuFrameTime, out gpuFrameTime); cpuFrameRate = (int)(1.0f / (cpuFrameTime / frameCount)); gpuFrameRate = (int)(1.0f / (gpuFrameTime / frameCount)); } // Update frame rate text. cpuFrameRateText.text = cpuFrameRateStrings[Mathf.Clamp(cpuFrameRate, 0, maxTargetFrameRate)]; if (gpuFrameRate != 0) { gpuFrameRateText.gameObject.SetActive(true); gpuFrameRateText.text = gpuFrameRateStrings[Mathf.Clamp(gpuFrameRate, 0, maxTargetFrameRate)]; } // Update frame colors. for (int i = frameRange - 1; i > 0; --i) { frameInfoColors[i] = frameInfoColors[i - 1]; } // Ideally we would query a device specific API (like the HolographicFramePresentationReport) to detect missed frames. // But, many of these APIs are inaccessible in Unity. Currently missed frames are assumed when the average cpuFrameRate // is under the target frame rate. frameInfoColors[0] = (cpuFrameRate < ((int)(AppFrameRate) - 1)) ? missedFrameRateColor : targetFrameRateColor; frameInfoPropertyBlock.SetVectorArray(colorID, frameInfoColors); // Reset timers. frameCount = 0; stopwatch.Reset(); stopwatch.Start(); } // Draw frame info. if (window.activeSelf) { Matrix4x4 parentLocalToWorldMatrix = window.transform.localToWorldMatrix; //if (defaultInstancedMaterial != null) //{ // frameInfoPropertyBlock.SetMatrix(parentMatrixID, parentLocalToWorldMatrix); // Graphics.DrawMeshInstanced(quadMesh, 0, defaultInstancedMaterial, frameInfoMatrices, frameInfoMatrices.Length, frameInfoPropertyBlock, UnityEngine.Rendering.ShadowCastingMode.Off, false); //} //else //{ // If a instanced material is not available, fall back to non-instanced rendering. for (int i = 0; i < frameInfoMatrices.Length; ++i) { frameInfoPropertyBlock.SetColor(colorID, frameInfoColors[i]); Graphics.DrawMesh(quadMesh, parentLocalToWorldMatrix * frameInfoMatrices[i], defaultMaterial, 0, null, 0, frameInfoPropertyBlock, false, false, false); } //} } // Update memory statistics. ulong limit = AppMemoryUsageLimit; if (limit != limitMemoryUsage) { if (window.activeSelf && WillDisplayedMemoryUsageDiffer(limitMemoryUsage, limit, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, limitMemoryText, limitMemoryString, limit); } limitMemoryUsage = limit; } ulong usage = AppMemoryUsage; if (usage != memoryUsage) { usedAnchor.localScale = new Vector3((float)usage / limitMemoryUsage, usedAnchor.localScale.y, usedAnchor.localScale.z); if (window.activeSelf && WillDisplayedMemoryUsageDiffer(memoryUsage, usage, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, usedMemoryText, usedMemoryString, usage); } memoryUsage = usage; } if (memoryUsage > peakMemoryUsage) { peakAnchor.localScale = new Vector3((float)memoryUsage / limitMemoryUsage, peakAnchor.localScale.y, peakAnchor.localScale.z); if (window.activeSelf && WillDisplayedMemoryUsageDiffer(peakMemoryUsage, memoryUsage, displayedDecimalDigits)) { MemoryUsageToString(stringBuffer, displayedDecimalDigits, peakMemoryText, peakMemoryString, memoryUsage); } peakMemoryUsage = memoryUsage; } window.SetActive(isVisible); }
void OnGUI() { int w = Screen.width, h = Screen.height; ypos = 0; Rect rect; string text; GUIStyle style = new GUIStyle(); #region defaultPrints if (showFPS) { ypos += 20; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; style.normal.textColor = flipflopColor ? flipflopColor_1 : flipflopColor_2; float msec = deltaTime * 1000.0f; float fps = 1.0f / deltaTime; text = string.Format("{0:0.0} ms ({1:0.} fps)", msec, fps); GUI.Label(rect, text, style); flipflopColor = !flipflopColor; } if (show_ms) { ypos += 20; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; style.normal.textColor = flipflopColor ? flipflopColor_1 : flipflopColor_2; FrameTiming[] timing = new FrameTiming[1]; FrameTimingManager.CaptureFrameTimings(); uint framesCaptured = FrameTimingManager.GetLatestTimings(1, timing); if (framesCaptured > 0) { text = "cpu: " + timing[0].cpuFrameTime + "ms || gpu: " + timing[0].gpuFrameTime + "ms"; } else { text = "could not get frame timings"; } GUI.Label(rect, text, style); flipflopColor = !flipflopColor; } if (showSystemLanguage) { ypos += 20; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; style.normal.textColor = flipflopColor ? flipflopColor_1 : flipflopColor_2; text = "System language: " + Application.systemLanguage.ToString(); GUI.Label(rect, text, style); flipflopColor = !flipflopColor; } if (showGPU) { ypos += 20; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; style.normal.textColor = flipflopColor ? flipflopColor_1 : flipflopColor_2; text = "graphics Device: " + SystemInfo.graphicsDeviceName + " " + SystemInfo.graphicsDeviceVendor + " " + SystemInfo.graphicsDeviceVersion + " " + SystemInfo.graphicsMemorySize; GUI.Label(rect, text, style); flipflopColor = !flipflopColor; } #endregion #region userLists if (showCustomMessages) { if (staticStringMessages.Count > 0) { foreach (Message message in staticStringMessages) { ypos += 20; style.normal.textColor = message.color; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; text = message.text; GUI.Label(rect, text, style); } } if (staticMessages.Count > 0) { foreach (RefMessage message in staticMessages) { ypos += 20; style.normal.textColor = message.color; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; text = message.prefix; if (message.FieldReferenced) { text += message.fieldInfo.GetValue(message.obj).ToString(); } else if (message.PropertyReferenced) { text += message.propertyInfo.GetValue(message.obj).ToString(); } else { style.normal.textColor = Color.red; text += "unaccessible variable! make sure it's a public variable and that the name given is written correctly (" + message.parameterName + ")"; } GUI.Label(rect, text, style); } } if (tempMessages.Count > 0) { ypos += 20; foreach (Message message in tempMessages) { ypos += 20; style.normal.textColor = message.color; rect = new Rect(0, ypos, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; text = message.text; GUI.Label(rect, text, style); } } if (staticStringMessagesAtPosition.Count > 0) { foreach (System.Tuple <Message, Vector2> message in staticStringMessagesAtPosition) { style.normal.textColor = message.Item1.color; rect = new Rect(message.Item2.x, message.Item2.y, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; text = message.Item1.text; GUI.Label(rect, text, style); } } if (staticMessagesAtPosition.Count > 0) { foreach (System.Tuple <RefMessage, Vector2> message in staticMessagesAtPosition) { style.normal.textColor = message.Item1.color; style.alignment = TextAnchor.UpperLeft; rect = new Rect(message.Item2.x, message.Item2.y, w, h * 2 / 100); style.fontSize = h * 2 / 90; text = message.Item1.prefix; if (message.Item1.FieldReferenced) { text += message.Item1.fieldInfo.GetValue(message.Item1.obj).ToString(); } else if (message.Item1.PropertyReferenced) { text += message.Item1.propertyInfo.GetValue(message.Item1.obj).ToString(); } else { style.normal.textColor = Color.red; text += "unaccessible variable! make sure it's a public variable and that the name given is written correctly (" + message.Item1.parameterName + ")"; } } } if (tempMessagesAtPosition.Count > 0) { ypos += 20; foreach (System.Tuple <Message, Vector2> message in tempMessagesAtPosition) { style.normal.textColor = message.Item1.color; rect = new Rect(message.Item2.x, message.Item2.y, w, h * 2 / 100); style.alignment = TextAnchor.UpperLeft; style.fontSize = h * 2 / 90; text = message.Item1.text; GUI.Label(rect, text, style); } } } #endregion }
private void Update() { if (UseFrameTiming) { FrameTimingManager.CaptureFrameTimings(); } if (Input.GetKeyDown(KeyCode.F5)) { if (active) { active = false; } else { active = true; } Panel.SetActive(active); } // measure average frames per second m_FpsAccumulator++; if (Time.realtimeSinceStartup > m_FpsNextPeriod) { avgaccum++; AVGTime += (Time.deltaTime - AVGTime) / avgaccum; m_CurrentFps = (int)(m_FpsAccumulator / fpsMeasurePeriod); if (LimitFpsHere) { Application.targetFrameRate = FramerateLimit; } m_FpsAccumulator = 0; m_FpsNextPeriod += fpsMeasurePeriod; uint ResultCount = 0; if (UseFrameTiming) { ResultCount = FrameTimingManager.GetLatestTimings(1, Times); } string Output = "FPS " + m_CurrentFps + " " + (AVGTime * 1000).ToString("00.00") + "ms"; if (Times.Length > 0 && ResultCount > 0) { Output += " CPU: " + Times[0].cpuFrameTime + "ms GPU: " + Times[0].gpuFrameTime + "ms"; } m_Text.text = Output; if (avgaccum > 10) { avgaccum = 1; } } if (m_CurrentFps >= FramerateLimit) { m_Text.color = Color.blue; } else if (m_CurrentFps >= TargetFps) { m_Text.color = Color.green; } else if (m_CurrentFps < 60) { m_Text.color = Color.red; } else if (m_CurrentFps <= 30) { m_Text.color = Color.red; } }