【Unity】フレームレートを計算して描画したかったから自作してみた。
どもども。Unityでゲーム作ってる学生です。
今回はフレームレートを計算して描画したかったので、コードを書きました。
え?Unity既存のを使えばいいって?
確かにそうです。
でもビルドした時にも確認したい時ってあるじゃないですか?(僕だけかも)
そういう時にでも使えるのが今から書くScriptなんですね。
ほぼ自己満足で作ってますが、なにか制作の参考になればと。
早速書いていきますよと。
まずUnity内の適当な場所にScriptを作成します。(名前はおまかせします。)
変数を宣言していきます。
色々書いてありますが、コピペで大丈夫です。多分。
using UniRx と using UniRx.Triggersは、のちのち必要なので先に宣言しておきます。
using UnityEngine;
using UniRx; ← これ必要
using UniRx.Triggers; ← これ必要
public class FPSDebugger : MonoBehaviour
{
[Header("DebugMode")]
[SerializeField] private bool debugMode = true;
[Header("フレームレート更新速度")]
private float updateFrame;
[Header("フォントサイズ")]
[SerializeField] private int fontSize = 10;
[Header("最大フレームレート数")]
public int maxFrameRate;
[Tooltip("フレームレート更新")]
private readonly float updateRateSpeed = 1f;
[Tooltip("Instance")]
private static FPSDebugger instance;
[Tooltip("FPS値格納変数")]
private float fps;
[Tooltip("フレームカウンター")]
private int frames;
[Tooltip("計算するタイミング")]
private float timeLeft;
[Tooltip("積み重ねた最大数")]
private float accum;
[Tooltip("GUIStyle")]
private GUIStyle guiStyle = new GUIStyle();
}
続いて関数を書いていきます。
まずはAwake関数。
最初のif文は、「シーンが読み込まれた際に、自分自身が存在しているか」を判断する条件式になります。
シーンに存在していなければ、自分自身が消えないObjectになり、存在していれば、自分自身は抹消されます。
つまり、シーンに1つしか存在しないObjectとして扱われるのです。(すごい!)
その下の updateFrame は、1秒に1回フレームレートを取得する設定にしています。
その下の Application.targetFrameRate = maxFrameRate は、この記事をみているであろう読者様が作成されているアプリケーションの「最大フレーム数」を決めています。
例えば 60と入力すればゲームは60FPSで更新されることになります。
そういうことです。
private void Awake()
{
if(!instance)
{
instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
updateFrame = Time.time + 1f;
Application.targetFrameRate = maxFrameRate;
}
続いて。
私が作ったものはOnGUI関数で描画しています。
もしDebugModeがtrueだったら、下の処理に入ります。
ここではUniRxについて省略しますが、軽く説明をしておきます。
this.UpdateAsObservable() は毎フレーム更新してくれる関数です。
下のWhereは条件がtrueの場合のみ通過する、いわばフィルターです。
Subscribeは実行内容です。 ほぼif文と同じなので分かりやすいかも。
ほんで、中身をごちゃごちゃ書いてますね。
最終的に fps っていうfloat型の変数にフレームレートの値を入れています。
描画に関しては下の3行のみですね。
GUIStyleを使うと色々といじれるらしいので使ってみました。
fps.ToString("f0") で数値をstring型に変換しています。
ちなみに "f0" っていうのは、小数点以下を描画するかどうからしいです。
0にすると整数として描画され、1にすると小数第一位まで描画されます。
ここは人それぞれなので、ご自由に変えてください。
private void OnGUI()
{
if(debugMode)
{
this.UpdateAsObservable()
.Where( _=> Time.time >= updateFrame)
.Subscribe(_ =>
{
timeLeft -= Time.deltaTime;
accum += Time.timeScale / Time.deltaTime;
frames++;
if (0 < timeLeft) return;
fps = accum / frames;
timeLeft = updateRateSpeed;
updateFrame += 1;
accum = 0;
frames = 0;
});
guiStyle.fontSize = fontSize;
GUI.color = Color.black;
GUI.Label(new Rect(10f, 10f, 200f, 90f), "FPS : " + fps.ToString("f0") + " FPS", guiStyle);
}
}
さあラストスパート!
このScriptだけでは動かないので、シーン上に置いてみましょう。
空のGameObjectを作成して、先程作ったScriptを貼り付け。
シーンが複数ある場合はPrefab化しておくといいでしょう。
インスペクター内の debugMode を true にしておくと、プロジェクトを実行した際に左上にフレームレートが描画されるはずです。多分。
これ、trueにしておくとビルドした際にもフレームレート描画されるんで、別のScriptから描画するかどうか選択できるようにしてもいいかもですね。
夢が広がるねぇ~^^
今回はここらへんで終了します。
今後もUnityのゲーム開発とかツール作成とかの情報を発信していくので、フォローとか色々頂けると励みになります。多分。
それでは。