LoginSignup
24
21

More than 5 years have passed since last update.

【Unity】 UniRxでFPSカウンタを作ってみる

Last updated at Posted at 2015-09-26

UniRxについての記事のまとめはこちら


UniRxを使ってFPSカウンタを作ってみました。

FPSカウンタ
using UnityEngine;
using System.Linq;
using UniRx;
using UniRx.Triggers;

public class FPSCounter : MonoBehaviour
{
    [SerializeField] private int bufferSize = 5; //バッファサイズ
    public ReadOnlyReactiveProperty<float> FpsReactiveProperty;

    private void Awake()
    {
        FpsReactiveProperty = this.UpdateAsObservable()
            .Select(_ => Time.deltaTime)   //Time.deltaTimeに変換
            .Buffer(bufferSize, 1)         //過去bufferSize分バッファ
            .Select(x => 1.0f/x.Average()) //平均値からfps算出
            .ToReadOnlyReactiveProperty();

        FpsReactiveProperty.Subscribe(x => Debug.Log(x));
    }
}

解説

上記のコードは、過去bufferSize分のTime.deltaTimeの平均値を取りそこからFPSを算出しています。
そしてストリームをReadOnlyReactivePropertyに変換し、publicとして公開しています。

注意すべき点としては、FpsReactivePropertyの初期化のタイミングです。
FpsReactivePropertyの初期化が終わる前に別のコンポーネントがFpsReactivePropertyをSubscribeしてしまうとNullReferenceExceptionが発生してしまうので注意しましょう。

追記

Static Propertyにしてしまったほうが取り回しが良いとのご指摘を@neueccさんより受けましたのでそちらのバージョンを記載します。

public static class FPSCounter
{
    const int BufferSize = 5; //サンプル数を変えたい場合はここを変える
    public static IReadOnlyReactiveProperty<float> Current { get; private set; }

    static FPSCounter()
    {
        Current = Observable.EveryUpdate()
            .Select(_ => Time.deltaTime)
            .Buffer(BufferSize, 1)
            .Select(x => 1.0f / x.Average())
            .ToReadOnlyReactiveProperty();
    }
}

こちらのメリットとしては、MonoBehaviourに全く関係ない場所から何も考えずに呼び出してfpsが取得できるという点です。

呼び出し方
FPSCounter.Current.Subscribe( fps => Debug.Log(fps) );
24
21
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
21