我的FPS计数器在精确的任何想法,为什么?(My FPS Counter is in-accurat

2019-10-24 14:23发布

当我开始了我的游戏它总是在那里95-101瞬息万变,在所有这些数字之间的..但是当我打开了统计栏我得到鞋面200的低点300的

所以想知道这是为什么,还是新的C#这样很容易对我笑。 继承人的代码,在此先感谢一如既往^ _ ^。

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);
    }
}

Answer 1:

为了显示一个有意义的FPS率你需要测量多少帧被渲染过的一定时间内 ,例如一秒 。 那么只有时间后,你在屏幕上显示的计算值。 这将每秒平均帧提供,而不是每秒瞬时帧 ,因为它会导致广泛波动值,其中后者不是在大多数情况下是特别有用的。

首先定义某些字段:

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

然后在您的渲染方法,你递增_framesRendered 。 您还检查是否由于周期的开始就过去一秒:

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          
}

跨技术

应当指出的是,上面的代码不作任何特定用途的统一,同时仍然是相当准确的,并与许多框架和API,例如兼容DirectX; OpenGL的; XNA; WPF甚至WinForms的。

当我开始了我的游戏它总是在那里95-101瞬息万变,在所有这些数字之间的..但是当我打开了统计栏我得到鞋面200的低点300的

华硕VG248QE为1ms和最大可以做的是144Hz,因此不太可能你得到“鞋面200的低点300的”。 当VSYNC关闭非GSYNC监视器上FPS是没有意义的。 是您的VSYNC开启?



Answer 2:

OnGUI函数在拉斯调用两次每帧(有时更多)。 您正在计算“FPS”里面OnGUI所以它几乎不会是准确的。

定义:

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

会带来最接近真实的FPS值,但如果你calc下它OnGUI方法将是不准确的。

我猜(不知道),你应该使用FixedUpdate()代替OnGUI()来calc下你的FPS。 (你也并不需要改变你的DeltaTime通过0.05f繁殖,如果你使用FixedUpdate)



Answer 3:

在Unity,FPS是相当于数Updates发生在1秒。 这是因为Update()被调用每Time.deltaTime秒。

InvokeRepeating方法

您还可以使用InvokeRepeating ,而只使用整数,这样来实现自己的FPS计数器:

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

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

void Update()
{
    FrameCounter++;
}

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

然后,只需显示Fps在可变OnGUI()方法。 使用这种方法,你的Fps值将得到每秒更新一次; 如果你想更频繁的更新,改变的最后一个参数InvokeRepeating呼叫,然后调整Fps相应计算。

但是请注意,这InvokeRepeating需要Time.timeScale考虑进去,所以例如,如果您暂停与游戏Time.timeScale = 0f; 直到暂停游戏计数器将停止更新。

FixedUpdate方法

另一种方法是计算在FPS FixedUpdate()方法,而不是OnGUI()Update() 调用此方法每Time.fixedDeltaTime秒,这是永远不变的,不管是什么。 值Time.fixedDeltaTime可以在全球范围的项目通过菜单设置Edit->Project Settings->Time ,项目Fixed Timestep

在这种情况下,你会数帧以同样的方式(在Update ),但更新您的FPS计数器FixedUpdate -这基本上是一样打电话给你自己的方法与InvokeRepeating("CountFps", 0f, 0.02f) 0.02f感一个典型的Time.fixedDeltaTime值,但是这取决于你的项目设置,按上文)。

结论

大多数时候,你会不会需要更新显示FPS经常,所以我个人喜欢用InvokeRepeating方法和1秒的间隔。



文章来源: My FPS Counter is in-accurate any ideas why?