Search Unity

Discussion Managing automatic quality based on current FPS

Discussion in 'Editor & General Support' started by angeldevelopment, Apr 24, 2023.

  1. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    247
    We have a game that is a high quality 3D mobile game. As such, some mobile devices struggle to run it. Thus, there are 3 quality levels. (Low, normal, high) Many devices, particularly older ones such as androids, struggle on normal quality (the default setting). Thus we decided the add a quality controller that samples the fps, for some intervals, determines the average, and changes to quality level to low if the fps is lower than a set amount.

    We wanted to post this script, and get some feedback about it, as well as any other ways to go about doing this. Currently the script will run every time the application is started, and it samples the first 5 fps readings, and disregards the first. If the average fps is lower than 26 the quality is changed. Any feedback/thoughts are greatly appreciated!


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class QualityController : MonoBehaviour
    6. {
    7.     // Start is called before the first frame update
    8.     private static QualityController instance;
    9.     private static readonly int FPS_QUALITY_SWITCH_VALUE = 26;
    10.  
    11.     private int counter;
    12.     private float pollingTime = 1;
    13.     private float frameCounter;
    14.     private float time;
    15.     private int currentFPS;
    16.  
    17.     private List<int> fpsTracker;
    18.  
    19.     void Start()
    20.     {
    21.         if (instance == null) {
    22.             // if no instance exists
    23.             DontDestroyOnLoad(gameObject);
    24.             fpsTracker = new();
    25.             instance = this;
    26.             print("[QUALITY CONTROLLER]: Did set instance.");
    27.         } else {
    28.             // destroy
    29.             print("[QUALITY CONTROLLER]: Instance exists, will destroy!");
    30.             Destroy(gameObject);
    31.         }
    32.     }
    33.  
    34.     // Update is called once per frame
    35.     void Update()
    36.     {
    37.         // increment frames
    38.         frameCounter += 1;
    39.         // get time elapsed
    40.         time += Time.deltaTime;
    41.         // calculate fps
    42.         if (time >= pollingTime) {
    43.  
    44.             counter ++;
    45.  
    46.             currentFPS = Mathf.RoundToInt(frameCounter / time);
    47.             print("[QUALITY CONTROLLER]: Current FPS - "+currentFPS);
    48.  
    49.            
    50.             if (counter != 1) {
    51.                 // skip first
    52.                 fpsTracker.Add(currentFPS);
    53.  
    54.                 if (counter == 5) {
    55.                     RunQualityCheck();
    56.                 }
    57.             }
    58.  
    59.             time -= pollingTime;
    60.             frameCounter = 0;
    61.         }
    62.     }
    63.  
    64.     void RunQualityCheck() {
    65.  
    66.         print("[QUALITY CONTROLLER]: Running initial quality check...");
    67.  
    68.         int total = 0;
    69.  
    70.         foreach(int i in fpsTracker) {
    71.             // count all frame sampled
    72.             total += i;
    73.         }
    74.  
    75.         // calculate average fps
    76.         float averageFPS = total / fpsTracker.Count;
    77.  
    78.         print("[QUALITY CONTROLLER]: total frames: "+total+", sampled: "+fpsTracker.Count+", AVERAGE FPS: "+averageFPS);
    79.  
    80.         if (averageFPS < FPS_QUALITY_SWITCH_VALUE) {
    81.             print("[QUALITY CONTROLLER]: Lowering quality!");
    82.             // change quality to low, 0
    83.             GameAdmin.SetQuality(0);
    84.             // Look for a settings manager, if it exists update the UI
    85.             var settingsManager = GameObject.FindObjectOfType<SettingsManager>();
    86.             // if it exists update it
    87.             if (settingsManager != null) {
    88.                 print("[QUALITY CONTROLLER]: will update settings manager");
    89.                 settingsManager.initialize();
    90.             }
    91.         }
    92.     }
    93. }
    94.  
     
  2. angeldevelopment

    angeldevelopment

    Joined:
    Sep 28, 2022
    Posts:
    247
    Anyone have any thoughts on this? Would like feedback before it is pushed in the next update :)