How do I find out how many FPS my project is running at?

So I’m curious to know how many FPS my project is running at and I read that if I clicked on play and then clicked on “Stats” it would display the FPS.
However when I do this it displays the FPS somewhere between 3000 and 4000 frames per second. Is this normal? I was under the impression that games run between 30 to approximately 120 FPS usually?

Here is a video of me clicking on Stats when my project is running:

Any advice would be appreciated.

That number is “accurate” except that the Stats window is notoriously inaccurate :smile:.

But yes since you have basically nothing in your scene, and your main loop is taking .2ms, your game is indeed running at 4000 frames per second.

Don’t worry, when you add stuff to the scene, it will start to slow down. Youi can also use Application.targetFramerate and/or VSync to limit the framerate of the game (and I would recommend doing so for power saving and thermal reasons).

I know I’m going off on a bit of a tangent but what confuses me is if I was to write the following in a script attached to a game object:

void Update(){

transform.Translate(0,-1,0);

}

I would be right in saying the game object would be travelling downwards at -1f between 3000 to 4000ths of a second?

But if I used FixedUpdate instead this code will run at zero, once or many times per second based on how many FPS are set in the time settings in the Unity editor? Even though when I look at the time settings in my Unity editor it doesn’t seem to show FPS as you can see here: https://ibb.co/TK98syz

I’ve been told numerous times that putting physics code inside of FixedUpdate is better than putting it in Update but I still don’t understand why? I’ve watched a couple of Youtube videos on it but I still don’t get it…is it that you have more control over the frame rate when using FixedUpdate?

That code will make your object move down by one unit every frame. If your framerate is 3000FPS, your object will move down one unit 3000 times each second (once every frame).

Framerate has nothing to do with the time settings in the editor. Framerate is a function of how fast your computer can execute one pass of the game loop. The game loop is everything in the diagram you can see here: Unity - Manual: Order of execution for event functions. It includes processing input, running all of your Start, Update, LateUpdate, etc… functions, drawing the game to the screen, and much more. The faster your computer is, and the less stuff you give it to do, the faster your computer can rip through everything and perform one pass of that diagram. If you don’t set a target framerate or vSync, your computer will run through the loop as fast as it possibly can and start a new one as soon as possible.

FixedUpdate runs as part of that normal game loop. Except that Unity checks how much time has passed since the last FixedUpdate ran, and if not enough time has elapsed, it doesn’t run it. If too much time has passed, it might run it twice or even more to catch up.

The reason to do physics stuff in FixedUpdate is because all of Unity’s Physics engines (there are 3 of them!) are what is called “fixed timestep” simulations. Every time Unity runs the physics simulation, it simulates the passage of a fixed, discrete amount of time. By default in Unity this is set to .02 seconds. So Unity provides FixedUpdate which is a function that runs right before that discrete amount of time in the physics simulation is about to run. You do it at a fixed rate so that the physics simulation (which is designed to ruin at a fixed rate) matches up with the passage of time in real life.

That is in comparison to Update which runs as fast as your computer will allow.

1 Like

About that, we can set limits to the framerate but we cannot, apparently, get the actual framerate. Why isn’t there an “Application.getFramerate” function?

I’m personally still looking for a reliable FPS counter script for Unity, would you know of one? :slight_smile:

Well - the “instantaneous” framerate is by definition 1 / Time.unscaledDeltaTime. That’s reliable and accurate. The problem comes into play when you want to apply some kind of “smoothing” or averaging to that value, as it can be very “jittery” frame-to-frame.

2 Likes

Thanks for the very detailed answer.

What is the purpose of simulating this fixed passage of time? And why is it set at 0.02 seconds by default?

It’s important to use a fixed timestep for physics to ensure that, given the same set of initial conditions, you always get the same results. You wouldn’t want the game to behave differently depending on the framerate. For example, you wouldn’t want someone who has a faster computer to see the player jumping higher or falling faster or the like. That kind of thing will happen with a variable framerate. It’s a little complex to explain why - but the gist of it is that accelerations over time can’t behave predictably when you don’t have a consistent time step.

Why .02? I have no idea, but that’s what they chose.

As for getting the FPS, just stick this on some GameObject somewhere, and call FPS.GetCurrentFPS() from anywhere whenever you want the current FPS. It averages the FPS over a number of frames, so it doesn’t jump around wildly. You can take that value and assign it to a text field for display purposes, or whatever you want to use it for.

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

public class FPS : MonoBehaviour {

    public int MaxFrames = 60;  //maximum frames to average over

    private static float lastFPSCalculated = 0f;
    private List<float> frameTimes = new List<float>();

    // Use this for initialization
    void Start () {
        lastFPSCalculated = 0f;
        frameTimes.Clear();
    }
 
    // Update is called once per frame
    void Update () {
        addFrame();
        lastFPSCalculated = calculateFPS();
    }

    private void addFrame()
    {
        frameTimes.Add(Time.unscaledDeltaTime);
        if (frameTimes.Count > MaxFrames)
        {
            frameTimes.RemoveAt(0);
        }
    }

    private float calculateFPS()
    {
        float newFPS = 0f;

        float totalTimeOfAllFrames = 0f;
        foreach (float frame in frameTimes)
        {
            totalTimeOfAllFrames += frame;
        }
        newFPS = ((float)(frameTimes.Count)) / totalTimeOfAllFrames;

        return newFPS;
    }

    public static float GetCurrentFPS()
    {
        return lastFPSCalculated;
    }
}

I wrote this a long time ago for my own uses, so there’s probably a more efficient way of doing it, but it seems to work just fine for me. I don’t usually fix what isn’t broke, so haven’t looked at it in a while :stuck_out_tongue:

5 Likes

I suggest updating your script to use Time.unscaledDeltaTime instead of Time.deltaTime!

1 Like

Yeah that’s a good idea. In the projects I use it for I never change the timescale value, so I never ran into that problem. Good catch!

1 Like

It’s because frame rate can mean quite a few different things. Is it instantaneous frame rate (1 / deltaTime)? Is it the average over the last 100 ms? Last 200 ms? Last 500 ms? Last second? What would you even use this thing for that you cannot do with Time.deltaTime or Time.smoothedDeltaTime?

4 Likes

Thanks for the explanation. :slight_smile:

This is the code I have, It reflects the FPS count that displays in the stats view. I found it on the Unity Wiki and there are others, how good are they?

///FPS COUNTER
///Written by: Annop "Nargus" Prapasapong
///Created: 7 June 2012


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

public class FPSCounter : MonoBehaviour
{
    public int FramesPerSec { get; protected set; }

    [SerializeField] private float frequency = 0.5f;


    private Text counter;

    private void Start()
    {
        counter = GetComponent<Text>();
        counter.text = "";
        StartCoroutine(FPS());
    }

    private IEnumerator FPS()
    {
        for (; ; )
        {
            int lastFrameCount = Time.frameCount;
            float lastTime = Time.realtimeSinceStartup;
            yield return new WaitForSeconds(frequency);

            float timeSpan = Time.realtimeSinceStartup - lastTime;
            int frameCount = Time.frameCount - lastFrameCount;

            FramesPerSec = Mathf.RoundToInt(frameCount / timeSpan);
            counter.text = "FPS: " + FramesPerSec.ToString();
        }
    }
}

Image:

7154371--856690--Capture d’écran_2021-05-19_19-10-28.jpg

Thanks! :slight_smile:

1 Like

When you say that the object will move down one unit 3000 to 4000 times every second what does “one unit” actually represent distance wise in a scene? Does it represent a percentage of one of the squares of the grid that I can see in sceneview?

Every basic object (primitives and place holder objects) you can add to a scene is 1 unit x 1 unit x 1 unit for 3D shapes (except for cylinders and capsules that are 1x2x1) and 1 unit x 1 unit for 2D ones. Units can be whatever you want in terms of world distances.