Unity杂文——FPS计算并显示

  1. 自制游戏FPS显示工具
  2. 代码
  3. 代码解释

原文地址

自制游戏FPS显示工具

在游戏开发中,FPS(Frames Per Second)是一个非常重要的指标,它可以反映出游戏的流畅度和性能。为了帮助开发者更好地优化游戏性能,我们可以使用一个自制的游戏FPS显示工具,实时显示当前的帧率。

代码

以下是自制的游戏FPS显示工具的代码实现:

public class FPSUtils : MonoBehaviour
{
    #region 实例化
    
    private static FPSUtils s_FPS = null;
    /// <summary>
    /// 实例化一个FPS单位
    /// </summary>
    /// <param name="parent"></param>
    public static void CreateInstance(GameObject parent = null)
    {

        if (s_FPS != null) return;

        var go = new GameObject("FPS");
        s_FPS = go.AddComponent<FPSUtils>();
        if (null == parent)
        {
            DontDestroyOnLoad(go);
        }
        else
        {
            go.SetParent(parent);
            go.SetAsFirstSibling();
        }
    }

    /// <summary>
    /// 销毁一个FPS单位
    /// </summary>
    public static void DestroyInstance()
    {
        if (null != s_FPS)
        {
            Destroy(s_FPS.gameObject);
            s_FPS = null;
        }
    }

    #endregion

    #region FPS统计

    /// <summary>
    /// 是否显示FPS
    /// </summary>
    private bool m_IsShowFPS = true;
    /// <summary>
    /// 帧数计算刷新时间(s)
    /// </summary>
    private const float m_ShowTime = 1f;
    /// <summary>
    /// 当前时间
    /// </summary>
    private float m_CurTime = 0f;
    /// <summary>
    /// 当前帧数
    /// </summary>
    private static int m_Frames = 0;
    /// <summary>
    /// 临时FPS
    /// </summary>
    private int m_TempFPS = 0;
    /// <summary>
    /// 帧数变化比较容忍度
    /// </summary>
    private const int TOLERANCE = 5;
    /// <summary>
    /// 当前FPS
    /// </summary>
    private int m_CurFPS;
    /// <summary>
    /// 当前显示的帧数
    /// </summary>
    private int m_CurShowFPS;
    /// <summary>
    /// 品质当前时间
    /// </summary>
    private float m_QualityCurTime = 0f;
    /// <summary>
    /// 品质的容忍度
    /// </summary>
    private const int m_TotalTime = 10;
    /// <summary>
    /// 帧数容忍度
    /// </summary>
    private const int m_MaxFrameCount = 200;
    /// <summary>
    /// 最小FPS容忍度
    /// </summary>
    private const int m_MinFPS = 10;
    
    /// <summary>
    /// 当前最小帧数
    /// </summary>
    private int m_CurMinFrmCount = 0;

    private void Update()
    {
        m_CurTime += Time.unscaledDeltaTime;
        m_Frames++;
        m_CurFPS = (int)(1.0f / Time.unscaledDeltaTime);
        if (m_CurTime >= m_ShowTime)
        {
            m_CurShowFPS = (int)(m_Frames / m_CurTime);
            if (Math.Abs(m_CurShowFPS - m_TempFPS) > TOLERANCE)
            {
                m_TempFPS = m_CurShowFPS;
            }
            m_CurTime = 0;
            m_Frames = 0;
        }
    }

    private void FixedUpdate()
    {
        m_QualityCurTime += Time.unscaledDeltaTime;
        if (m_QualityCurTime >= m_TotalTime)
        {
            m_CurMinFrmCount = 0;
            m_QualityCurTime = 0;
        }

        if (m_CurFPS >= m_MinFPS) return;

        m_CurMinFrmCount++;
        if (m_CurMinFrmCount > m_MaxFrameCount)
        {
            //检测到帧率过低,可以做切换品质的功能
        }
    }

    /// <summary>
    /// 绘制FPS
    /// </summary>
    private void OnGUI()
    {
        if (m_IsShowFPS)
        {
            var fpsStr = $"FPS:{m_CurShowFPS}";
            GUI.Label(new Rect(0, 0, 100, 20), fpsStr);
        }
    }

    #endregion
}
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146

代码解释

以上代码中,FPSUtils类继承自MonoBehaviour,用于实现FPS统计和显示。

首先,定义了一个静态的CreateInstance方法,用于创建一个FPSUtils实例。在该方法中,首先判断是否已经存在一个FPSUtils实例,如果存在则直接返回。如果不存在,则创建一个新的GameObject对象,并将FPSUtils组件添加到该对象上。如果指定了parent参数,则将新创建的对象设置为该parent对象的第一个子对象,否则将其设置为不会被销毁的对象。

然后,定义了一个静态的DestroyInstance方法,用于销毁FPSUtils实例。在该方法中,首先判断是否存在FPSUtils实例,如果存在则销毁该实例,并将其设置为null。

接下来,定义了一些用于FPS统计的变量,包括是否显示FPS、帧数计算刷新时间、当前时间、当前帧数、临时FPS、帧数变化比较容忍度、当前FPS、当前显示的帧数、品质当前时间、品质的容忍度、帧数容忍度、最小FPS容忍度、当前最小帧数等。

然后,在Update方法中,每帧更新当前时间、帧数和当前FPS。如果当前时间超过了帧数计算刷新时间,则计算当前显示的帧数,并将临时FPS设置为当前显示的帧数。在计算当前显示的帧数时,如果当前显示的帧数与临时FPS的差值超过了帧数变化比较容忍度,则将临时FPS设置为当前显示的帧数,并将当前时间和帧数重置为0。

在FixedUpdate方法中,每帧更新品质当前时间和当前最小帧数。如果当前FPS大于等于最小FPS,则直接返回。如果当前FPS小于最小FPS,则将当前最小帧数加1。如果当前最小帧数超过了帧数容忍度,则可以做一些切换品质的功能。

最后,在OnGUI方法中,如果需要显示FPS,则绘制当前显示的帧数。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 841774407@qq.com

×

喜欢就点赞,疼爱就打赏