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) );