using UnityEngine; namespace Gaia { public class FrameRateManager : MonoBehaviour { public bool m_showFPS = true; public bool m_showGUI = true; public bool m_autoQualityManagement = true; public float m_autoCheckInterval = 10f; public int m_targetFrameRate = 60; public int m_fontSize = 25; private float m_autoCheckTimeLeft; private int m_currentQuality; private int m_maxQuality = 1; private string[] m_qualityNames; private float m_fpsUpdateInterval = 0.5f; private float m_fpsAccum; private int m_fpsFrames; private float m_fpsTimeLeft; private float m_fpsValue; private string m_fpsValueStr = string.Empty; private GUIStyle m_fpsStyle = new GUIStyle(); private GUIStyle m_fpsShadowStyle = new GUIStyle(); private Rect m_fpsLocation = new Rect(5f, 5f, 100f, 25f); private Rect m_fpsShadowLocation = new Rect(6f, 6f, 100f, 25f); private void Start() { Application.targetFrameRate = m_targetFrameRate; m_maxQuality = QualitySettings.names.Length - 1; m_qualityNames = QualitySettings.names; m_currentQuality = QualitySettings.GetQualityLevel(); m_autoCheckTimeLeft = m_autoCheckInterval; Debug.Log("Current quality is " + m_qualityNames[m_currentQuality]); m_fpsStyle.fontSize = m_fontSize; m_fpsShadowStyle.fontSize = m_fontSize; m_fpsTimeLeft = m_fpsUpdateInterval; m_fpsLocation = new Rect(Screen.width - 250, 5f, 100f, 25f); m_fpsShadowLocation = new Rect(Screen.width - 250 + 1, 6f, 100f, 25f); } private void OnGUI() { if (!m_showFPS && !m_showGUI) { return; } if (m_showFPS) { GUI.Label(m_fpsShadowLocation, m_fpsValueStr, m_fpsShadowStyle); GUI.Label(m_fpsLocation, m_fpsValueStr, m_fpsStyle); } if (!m_showGUI) { return; } GUILayout.BeginVertical(); for (int i = 0; i <= m_maxQuality; i++) { if (GUILayout.Button(m_qualityNames[i])) { QualitySettings.SetQualityLevel(i, applyExpensiveChanges: true); m_currentQuality = i; UpdateQuality(); m_autoQualityManagement = false; } } GUILayout.EndVertical(); } private void Update() { m_fpsTimeLeft -= Time.deltaTime; m_fpsAccum += Time.timeScale / Time.deltaTime; m_fpsFrames++; if (m_fpsTimeLeft <= 0f) { m_fpsValue = m_fpsAccum / (float)m_fpsFrames; if (m_fpsValue < 30f) { m_fpsStyle.normal.textColor = Color.yellow; } else if (m_fpsValue < 10f) { m_fpsStyle.normal.textColor = Color.red; } else { m_fpsStyle.normal.textColor = Color.green; } m_fpsValueStr = $"{m_fpsValue:f0} {m_qualityNames[m_currentQuality].Substring(0, 3)}"; m_fpsTimeLeft = m_fpsUpdateInterval; m_fpsAccum = 0f; m_fpsFrames = 0; } if (!m_autoQualityManagement) { return; } m_autoCheckTimeLeft -= Time.deltaTime; if (m_autoCheckTimeLeft < 0f) { if (m_fpsValue + 10f >= (float)m_targetFrameRate) { IncreaseQuality(); } else if (m_fpsValue - 10f <= (float)m_targetFrameRate) { DecreaseQuality(); } m_autoCheckTimeLeft = m_autoCheckInterval; } } private void UpdateQuality() { if (QualitySettings.GetQualityLevel() != m_currentQuality) { Debug.Log("Changing quality to " + m_qualityNames[m_currentQuality]); switch (m_currentQuality) { case 0: Terrain.activeTerrain.treeDistance = 250f; Terrain.activeTerrain.treeBillboardDistance = 30f; Terrain.activeTerrain.treeCrossFadeLength = 5f; Terrain.activeTerrain.treeMaximumFullLODCount = 5; Terrain.activeTerrain.detailObjectDistance = 40f; Terrain.activeTerrain.detailObjectDensity = 0.1f; Terrain.activeTerrain.heightmapPixelError = 20f; Terrain.activeTerrain.heightmapMaximumLOD = 1; Terrain.activeTerrain.basemapDistance = 100f; break; case 1: Terrain.activeTerrain.treeDistance = 500f; Terrain.activeTerrain.treeBillboardDistance = 50f; Terrain.activeTerrain.treeCrossFadeLength = 10f; Terrain.activeTerrain.treeMaximumFullLODCount = 10; Terrain.activeTerrain.detailObjectDistance = 50f; Terrain.activeTerrain.detailObjectDensity = 0.25f; Terrain.activeTerrain.heightmapPixelError = 10f; Terrain.activeTerrain.heightmapMaximumLOD = 1; Terrain.activeTerrain.basemapDistance = 250f; break; case 2: Terrain.activeTerrain.treeDistance = 650f; Terrain.activeTerrain.treeBillboardDistance = 75f; Terrain.activeTerrain.treeCrossFadeLength = 25f; Terrain.activeTerrain.treeMaximumFullLODCount = 20; Terrain.activeTerrain.detailObjectDistance = 60f; Terrain.activeTerrain.detailObjectDensity = 0.4f; Terrain.activeTerrain.heightmapPixelError = 8f; Terrain.activeTerrain.heightmapMaximumLOD = 0; Terrain.activeTerrain.basemapDistance = 500f; break; case 3: Terrain.activeTerrain.treeDistance = 800f; Terrain.activeTerrain.treeBillboardDistance = 100f; Terrain.activeTerrain.treeCrossFadeLength = 40f; Terrain.activeTerrain.treeMaximumFullLODCount = 30; Terrain.activeTerrain.detailObjectDistance = 80f; Terrain.activeTerrain.detailObjectDensity = 0.7f; Terrain.activeTerrain.heightmapPixelError = 5f; Terrain.activeTerrain.heightmapMaximumLOD = 0; Terrain.activeTerrain.basemapDistance = 800f; break; case 4: Terrain.activeTerrain.treeDistance = 1000f; Terrain.activeTerrain.treeBillboardDistance = 150f; Terrain.activeTerrain.treeCrossFadeLength = 50f; Terrain.activeTerrain.treeMaximumFullLODCount = 50; Terrain.activeTerrain.detailObjectDistance = 120f; Terrain.activeTerrain.detailObjectDensity = 1f; Terrain.activeTerrain.heightmapPixelError = 5f; Terrain.activeTerrain.heightmapMaximumLOD = 0; Terrain.activeTerrain.basemapDistance = 1000f; break; case 5: Terrain.activeTerrain.treeDistance = 2000f; Terrain.activeTerrain.treeBillboardDistance = 200f; Terrain.activeTerrain.treeCrossFadeLength = 50f; Terrain.activeTerrain.treeMaximumFullLODCount = 100; Terrain.activeTerrain.detailObjectDistance = 150f; Terrain.activeTerrain.detailObjectDensity = 1f; Terrain.activeTerrain.heightmapPixelError = 5f; Terrain.activeTerrain.heightmapMaximumLOD = 0; Terrain.activeTerrain.basemapDistance = 1000f; break; } } } private bool IncreaseQuality() { if (m_currentQuality < m_maxQuality) { m_currentQuality++; UpdateQuality(); } return true; } private bool DecreaseQuality() { if (m_currentQuality > 0) { m_currentQuality--; UpdateQuality(); } return true; } } }