取消

如何在 Unity3D 场景中显示帧率(FPS)

本文介绍如何在 Unity3D 场景中显示帧率。


插入 UI:Text

做 FPS 帧率显示需要用到 UI 对象 Text,因此你需要有一个 Canvas。关于在 Unity3D 中插入 UI 对象的方法可见我的另一篇博客:

当添加了 Canvas 后,再在 Canvas 里添加 Text:

添加 Text

设置文本的属性和布局

选中文本对象,在 Inspector 窗格中有很多需要设置的属性。如下图所示。

设置属性和布局

锚点对齐

上图中,我把点击对齐格子的弹出框放到了场景空间中(截图而已,实际不能放),不然会遮挡窗口中的其他属性。

这里在水平和垂直方向上都分别可以设置 4 种对齐方式:

  • 左/上 对齐
  • 居中对齐
  • 右/下 对齐
  • 拉伸对齐

默认是水平垂直居中,于是 UI 对象会以场景的中心为参考点布局。如果你强行把文本对象拉到左上角,那么你会失去分辨率自适应的特性。

由于本文期望 FPS 显示到左上角,所以我把锚点设置成左上角。

相对位置,大小

接着,使用鼠标拖拽文本到合适的位置。也可以直接在 Inspector 窗口中设置 PosX 和 PosY 属性,这样更精确。

也许你注意到还有一个 PosZ 属性可以设置。如果你在 2D 视图中,那么你会发现设置这个属性是“无效”的,但只要切回 3D 视图,你就能发现还是有深度变化的。不过,在设置 Canvas 的 Render Mode 属性之前(保持默认值),这个设置依然还是没有意义,因为默认情况下 UI 在最终显示的时候是始终保持 2D 视图的。

可以拖拉鼠标调整文本框的大小,也可以设置 Width 和 Height 属性。

设置文本的文字内容、字体大小和颜色

在下面的 Text 组件里面,你还可以设置通常本文应该有的属性,调整到你觉得合适的值就好。

添加帧率计算脚本

接下来我们开始添加帧率计算脚本。

创建脚本

在 Inspector 窗口中添加 AddComponent 添加组件,选择新脚本,取个名字。

添加脚本

设计脚本属性

1
2
3
4
5
6
7
8
9
10
11
using UnityEngine;
using UnityEngine.UI;

public class FpsUpdater : MonoBehaviour
{
    public Text fpsText;

    void Update()
    {
    }
}

我们在脚本中公开一个属性 fpsText,用来在 Inspector 窗口中制定要更新的文本 UI。

然后,将文本对象拖到脚本的 Fps Text 属性上,这样我们就可以在脚本中直接使用 fpsText 字段拿到要更新文本的 Text 对象了。

设置 Fps Text 属性

当然,直接用 gameObject 也是可以的,不过需要自己再做类型转换。

编写代码

最简单的

最简单的获取 FPS 的方式是直接用 1 除以当前帧所经历的时间。

1
2
3
4
5
void Update()
{
    var fps = 1.0f / Time.deltaTime;
    fpsText.text = $"FPS: {fps}";
}

然而当你实际使用的时候你就会觉得——嗯……眼睛会瞎的。

闪烁的 FPS

你也有可能发现文字一时出现一时消失,那可能是因为你文本框的宽度设小了。于是当小数点后位数多了一些之后,显示不下去,文字就会消失。

至少,取个整还是需要的吧,谁愿意看小数帧数呢?

1
2
var fps = 1.0f / Time.deltaTime;
fpsText.text = $"FPS: {Mathf.Ceil(fps)}";

更稳定的

加了取整还是变化很快,看不清。那么可以如何更稳定呢?

可以考虑累加多帧再一次性更新。比如这里 60 帧更新一次:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using UnityEngine;
using UnityEngine.UI;

public class FpsUpdater : MonoBehaviour
{
    public Text fpsText;

    private int count;
    private float deltaTime;

    void Update()
    {
        count++;
        deltaTime += Time.deltaTime;

        if (count % 60 == 0)
        {
            count = 1;
            var fps = 60f/deltaTime;
            deltaTime = 0;
            fpsText.text = $"FPS: {Mathf.Ceil(fps)}";
        }
    }
}

稳定的帧率指示

或者考虑 0.5 秒更新一次:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public Text fpsText;

private int count;
private float deltaTime;

void Update()
{
    count++;
    deltaTime += Time.deltaTime;

    if (deltaTime >= 0.5f)
    {
        var fps = count/deltaTime;
        count = 0;
        deltaTime = 0;
        fpsText.text = $"FPS: {Mathf.Ceil(fps)}";
    }
}

每秒刷新一次的更稳定的帧率指示

更多脚本

更多 FPS 帧数显示的脚本,可以从本文末尾的参考资料处找到。有很多不同需求的(比如帧率过低飘红的设定,比如要精确)。


参考资料

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/unity-show-fps.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

知识共享许可协议

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])

登录 GitHub 账号进行评论