在Unity场景中计算帧率

8

我正在使用Unity和Vuforia扩展来制作增强现实项目。虽然我是初学C#,但我正在寻找类似于ARToolKit的getFrame()方法,但实在找不到。

我的问题是:

  1. 我是否需要计算场景操作的帧率?
  2. 我应该使用哪个场景对象来跟踪帧率?
6个回答

6
这很简单,只需要:
public float avgFrameRate;

public void Update()
{
    avgFrameRate = Time.frameCount / Time.time;
}

将此代码放入任何MonoBehaviour中,并将其附加到场景层次结构中的任何GameObject

请注意:这只会给出平均帧率。要获得更实时的帧率,其他答案提供了有效的解决方法。


6

这里提供的所有答案都没有考虑到Unity中 timescale 可以被修改,如果它被修改了,那么以上所有方法都是不正确的。因为 Time.Delta 是受到 timescale 影响的。

因此,你需要使用 Time.unscaledDeltaTime

int fps = 0;
void Update () {
    fps = (int)(1f / Time.unscaledDeltaTime);
}

3
你应该查看Time.smoothDeltaTime。它返回一个平滑的 Time.deltaTime 值,你可以使用它来代替其他答案中提到的平滑技术。

2

您需要像计时器一样的东西来跟踪时间,以及更新屏幕所需的时间,并从中推断出每秒绘制多少帧。

我对Unity不太熟悉,但我认为诸如1/Time.deltaTime之类的内容可以给您想要的结果。

所以您需要像这样的内容:

public void Update()
{
    framerateThisFrame = 1/Time.deltaTime;
}

下一步,您需要决定更改显示的FPS频率,因为每帧中的framerateThisFrame可能会经常变化。例如,您可能想每两秒更改一次。 编辑 您可能想要进行的改进是存储过去的n帧,并使用平均值来计算FPS,然后显示它。因此,您最终可以得到类似以下内容的东西:
public int Granularity = 5; // how many frames to wait until you re-calculate the FPS
List<double> times;
int Counter = 5;

public void Start ()
{
    times = new List<double>();
}

public void Update ()
{
   if (counter <= 0)
   {
       CalcFPS ();
       counter = Granularity;
   } 

   times.Add (Time.deltaTime);
   counter--; 
}

public void CalcFPS ()
{
    double sum = 0;
    foreach (double F in times)
    {
        sum += F;
    }

    double average = sum / times.Count;
    double fps = 1/average;

    // update a GUIText or something
}

编辑

如果你想应用减速/时间改变效果,甚至可以将帧时间乘以Time.timeScale,这样可以保持一致。


1

由于帧率可能会不断变化,因此在给定的一秒钟内会多次更改。我使用了以下推荐方法来获取当前帧率。只需将其放入新脚本中,并将其添加到场景中的新空游戏对象中。

float deltaTime = 0f;

void Update() {

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

}

源代码,包括显示方法:http://wiki.unity3d.com/index.php?title=FramesPerSecond


0
IEnumerator FramesPerSecond()
{
    while (true)
    {
        yield return new WaitForSeconds(1);
        Debug.LogFormat("Fps {0}", Time.frameCount/Time.time);

    }

}

private void Start()
{
    StartCoroutine(FramesPerSecond());
}

请阅读如何撰写优秀的答案?。虽然该代码块可以回答OP的问题,但是如果你解释一下这段代码与问题中的代码有何不同、你做了哪些更改、为什么要进行更改,以及为什么这样解决问题而不会引入其他问题,这个答案将会更加有用。 - Saeed Zhiany

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接