うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】FPS を測定する

FPS は Update を呼ばれた回数 / 呼び出しの合計時間 で求めることができるのでそれを利用して計算しています

どこからでも計測できるようにイベントを登録することで利用できるようにしてあり

呼ばれないときにインスタンスは無いので、無駄に動かないようにしています
また、イベントがなくなったタイミングで、インスタンスが削除されます

使い方

FrameRate.FPS += v => {
    // FPS の計算したタイミングで呼び出しされる
    Debug.Log(v);
}

コード

using UnityEngine;
 
namespace FrameRateUtil
{
    internal class FrameRateChecker : MonoBehaviour
    {
        private float _time;
        private int _frame;
 
        internal event FrameRate.FPSUpdateDelegate FPS;
 
        private void Update()
        {
            _time += Time.deltaTime;
            _frame++;
 
            if (_time < FrameRate.FPS_CHECK_INTERVAL)
                return;
 
            FPS?.Invoke(Mathf.RoundToInt(_frame / _time));
 
            _time -= FrameRate.FPS_CHECK_INTERVAL;
            _frame = 0;
        }
    }
 
    public static class FrameRate
    {
        public delegate void FPSUpdateDelegate(int frameRate);
        public static event FPSUpdateDelegate _fps;
 
        private static FrameRateChecker i;
        private static int eventCount;
 
        internal static float FPS_CHECK_INTERVAL = 0.5f;
 
        public static void ChangeInterval(float value)
        {
            FPS_CHECK_INTERVAL = value;
        }
 
        // FPS の更新イベント
        public static event FPSUpdateDelegate FPS
        {
            add
            {
                if (i == null)
                {
                    var obj = new GameObject(typeof(FrameRateChecker).Name);
                    Object.DontDestroyOnLoad(obj);
                    i = obj.AddComponent<FrameRateChecker>();
                    i.FPS += v => _fps?.Invoke(v);
                }

                _fps += value;
                eventCount++;
            }
            remove
            {
                _fps -= value;
                eventCount--;

                // 参照が0になればオブジェクトを削除する
                if (eventCount <= 0)
                {
                    Object.Destroy(i);
                }
            }
        }
    }
}