My FPS Counter is in-accurate any ideas why?

≯℡__Kan透↙ 提交于 2020-01-16 05:14:05

问题


When I start up my game it stays around 95-101 rapidly changing, in between all of those numbers.. but when I open up the stats bar I'm getting upper 200's low 300's

so wondering why that is still new to c# so be easy on me lol. heres the code thanks in advance as always ^_^.

float deltaTime = 0.0f;

void Update() 
{
    deltaTime += (Time.deltaTime - deltaTime) * 0.1f;
}

void OnGUI()
{
    int w = Screen.width, h = Screen.height;

    GUIStyle style = new GUIStyle ();

    Rect rect = new Rect (0, 0, w, h * 2 / 100);
    style.alignment = TextAnchor.UpperRight;
    style.fontSize = h * 2 / 100;
    style.normal.textColor = new Color (255.0f, 255.0f, 255.0f, 1.0f);
    float msec = deltaTime * 1000.0f;
    float fps = 1f / deltaTime;
    string text = string.Format ("({1:0.} fps)", msec, fps);
    GUI.Label (rect, text, style);
    }
}

回答1:


In order to display a meaningful FPS rate you need to measure how many frames were rendered over a constant period of time, for example one second. Then only after that period do you display the calculated value on screen. This will provide for an average frames per second as opposed to an instantaneous frames per second, the latter of which is not particularly useful in most cases as it leads to widely fluctuating values.

Code

First define some fields:

DateTime _lastTime; // marks the beginning the measurement began
int _framesRendered; // an increasing count
int _fps; // the FPS calculated from the last measurement

Then in your render method you increment the _framesRendered. You also check to see if one second has elapsed since the start of the period:

void Update()
{
    _framesRendered++;

    if ((DateTime.Now - _lastTime).TotalSeconds >= 1)
    {
        // one second has elapsed 

        _fps = _framesRendered;                     
        _framesRendered = 0;            
        _lastTime = DateTime.Now;
    }

    // draw FPS on screen here using current value of _fps          
}

Cross-technology

It should be pointed out that the above code makes no particular use of Unity whilst still being reasonably accurate and is compatible with many frameworks and APIs such as DirectX; OpenGL; XNA; WPF or even WinForms.

When I start up my game it stays around 95-101 rapidly changing, in between all of those numbers.. but when I open up the stats bar I'm getting upper 200's low 300's

The ASUS VG248QE is 1ms and the max it can do is 144Hz so it is unlikely you are getting "upper 200's low 300's". FPS is meaningless when VSYNC is turned off on a non-GSYNC monitor. Is your VSYNC turned on?




回答2:


OnGUI function is called at las twice per frame (sometimes more). You are calculating your "FPS" inside OnGUI so it will almost never be accurate.

Defining :

deltaTime += (Time.deltaTime - deltaTime) * 0.05f;

will bring your FPS values closest to real but it will not be accurate if you calc it on OnGUI method.

I guess (not sure) that you should use FixedUpdate() instead of OnGUI() to calc your FPS. (also you don't need to change your deltaTime to multiply by 0.05f if you use FixedUpdate)




回答3:


In Unity, FPS is equivalent to number of Updates that occur in 1 second. This is because Update() is called every Time.deltaTime seconds.

InvokeRepeating method

You can also use InvokeRepeating to implement your own FPS counter while using only integers, like this:

private int FrameCounter = 0;
private int Fps = 0;

void Start() 
{
    InvokeRepeating("CountFps", 0f, 1f);
}

void Update()
{
    FrameCounter++;
}

private void CountFps()
{
    Fps = FrameCounter;
    FrameCounter = 0;
}

Then just display the Fps variable in the OnGUI() method. Using this method, your Fps value will get updated every second; if you want more frequent updates, change the last argument of InvokeRepeating call and then adjust the Fps calculation accordingly.

Note, however, that InvokeRepeating takes Time.timeScale into account, so e.g. if you pause the game with Time.timeScale = 0f; the counter will stop updating until you unpause the game.

FixedUpdate method

Another approach is to count the FPS in FixedUpdate() method instead of OnGUI() or Update(). This gets called every Time.fixedDeltaTime seconds which is always the same, no matter what. The value of Time.fixedDeltaTime can be set globally for the project via menu Edit->Project Settings->Time, item Fixed Timestep.

In this case, you would count frames the same way (in Update), but update your FPS counter in FixedUpdate - which is basically the same as calling you own method with InvokeRepeating("CountFps", 0f, 0.02f) (0.02f being a typical Time.fixedDeltaTime value, but this depends on your project settings as per above).

Conclusion

Most of the time, you won't need to update the displayed FPS that often, so I personally like to use the InvokeRepeating method and 1 second intervals.



来源:https://stackoverflow.com/questions/31840902/my-fps-counter-is-in-accurate-any-ideas-why

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!