[SOLVED]This FPS counter method is right?

Hi. i am trying to count frame rate in 1 second. Writed a simple script but not sure. is this the right way?FPS text is a UI element. Here is code.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class stats : MonoBehaviour
{
    public Text gameFPS;  //UI element.
    public Text gameTime;

    private float fpsCounter = 0;
    private float currentFpsTime = 0;
    private float fpsShowPeriod = 1;

    // Update is called once per frame
    void Update()
    {
        currentFpsTime = currentFpsTime + Time.deltaTime;
        fpsCounter = fpsCounter + 1;
        if (currentFpsTime > fpsShowPeriod)
        {
            gameFPS.text = fpsCounter.ToString();
            currentFpsTime = 0;
            fpsCounter = 0;
        }

        gameTime.text = Mathf.Floor(Time.time).ToString();
    }
}

Nothing wrong with it. One thing to know that it’s not accurate in the editor though. I have one that tells me 120+ fps in the editor and 2000+ fps in a build.

While above will probably work, there are a couple of caveats:

  1. As Chris mentioned above, fps times will differ for Editor and standalone Player because Editor has a large Overhead.
  2. You are changing a UI text each pass though Update. This generates an update event for the whole canvas, adding a lot of overhead.You shuld only update once per second, or once every other second.
  3. If you look at Time.deltaTime (as you do), you may realize that you have the fps number right there. It’s the slice of a second the frame has taken. If you divide One by that number, you have the fps for that frame (example: DeltaTime is 1/10 of a second. You can fit 1 / (1/10) = 1/1 * 10 = 10 Frames into a second. You could either Display that directly, or sum and average n (maybe 200) of those, and display the average at the end of every n iterations.

-ch

Thanks Chris. In build it seems useful.

  1. Yes. I realise it. It could be useful, if it would show FPS for target platform.
  2. You are talking about this line → gameTime.text = Mathf.Floor(Time.time).ToString(); Will update it once a second.
  3. I thought count a number every Update and show it every 1 second wolud give me total frames per seconds:
    “fpsCounter = fpsCounter + 1” and
    “currentFpsTime = currentFpsTime + Time.deltaTime”
    if(currentFpsTime > 1){than show fpsCounter and time. Set variables to zero.}

if using 1 / (1/time.deltaTime) , taking “sum and average n” is sensible. am i right?

Well, fps does not have to be accumulated over a full second, just like you don’t have to drive a full hour to measure mp/h :slight_smile: So you can define an arbitrary number of samples to take, and update whenever you have taken enough samples:

public int count;
public int samples = 100;
public float totalTime;

public void Start(){
    count = samples;
    totalTime = 0f;
}

public void Update(){
    count -= 1;
    totalTime += Time.DeltaTime;

    if (count <= 0) {
        float fps = samples / totalTime;
        displayFPS(fps); // your way of displaying number. Log it, put it to text object…
        totalTime = 0f;
        count = samples;
    }
}

Note: you’ll have to go thorough the code, maybe the Count is off by 1.

3 Likes

Oh i understood. “just like you don’t have to drive a full hour to measure mp/h” is good example :slight_smile:

“fps = samples / totalTime;”

thanks for explanation csofranz.