【Unity】WebGLのフレームレート設定の落とし穴と解決方法
WebGLでの実行フレームレート設定は、iOS / AndroidやPCと同じ方法だと動きません。
unityroomで公開するときに重要となるので、対応方法と、フレームレート設定コンポーネントを紹介します。
※環境: Unity 2022.3.21f1
WebGLビルドでFPS指定が動かない
WebGLで動かないコード
貼り付けるとInspactorからFPS指定できるコンポーネント
using UnityEngine;
using UniRx;
public class TargetFPS : MonoBehaviour
{
public int FrameRate = 60;
private void Awake()
{
// フレームレートを設定する
Application.targetFrameRate = FrameRate;
// フレームレートが変更されたら、反映する
this.ObserveEveryValueChanged(x => x.FrameRate)
.Subscribe(_ => Application.targetFrameRate = FrameRate);
}
}
- iOS / Android / PCなどでは、こちらで問題なく動作
- WebGLだと効果がなく、60fps指定が無効になってしまう
- レベルアップラン のunityroom版で144fpsになり重くなっていることから発覚しました。
フレームレート指定が動かない原因
以下の書き込みで、原因と対応についても情報がありました。
targetFrameRate not working in 2021.3.1 LTS WebGL – Unity Engine – Unity Discussions
WebGLで以下のどちらかを満たす場合、強制的にモニターのリフレッシュレートが参照されてしまうようです。
QualitySettings.vSyncCount != 0
60 % Application.targetFrameRate == 0
つまり、任意のFPSを指定するには
vSyncCount
が OFF60 ÷ targetFrameRate
が割り切れない- 60fps, 30fps, 15fpsは割り切れるのでNG
- 59fps, 29fps, 14fpsならOK
WebGL対応フレームレート指定コード
using UnityEngine;
using UniRx;
public class TargetFPS : MonoBehaviour
{
public int FrameRate = 60;
private void Awake()
{
UpdateFPS();
this.ObserveEveryValueChanged(x => x.FrameRate)
.Subscribe(_ => UpdateFPS());
}
private void UpdateFPS()
{
#if UNITY_WEBGL
// https://discussions.unity.com/t/targetframerate-not-working-in-2021-3-1-lts-webgl/881482
// WebGLだとvSyncCountを0にし、60fpsではなく59fpsにしないと正常に動作しない
QualitySettings.vSyncCount = 0;
int frameRate = FrameRate;
if (60 % FrameRate == 0)
{
--frameRate; // 割り切れる場合は、-1しておく
}
Application.targetFrameRate = frameRate;
#else
Application.targetFrameRate = FrameRate;
#endif
}
}
これで、どのプラットフォームでもフレームレートを正しく指定できるようになりました。
まとめ
WebGL特有の挙動によってフレームレートが正しく反映できないとわかりました。
エディターでは、フレームレート指定が動いてしまうので普段からFPS表示をしていないと見落としてしまいます。
FPSのお手軽確認
FPS表示を手軽にやりたい人は、FEELやCorgi Engine, TopDown Engineに付属するMMFPSCounterをおいておくと簡単です。
画面右端に小さくFPSを表示できます。
↑
Corgi Engine, TopDown Engineには、FEELや関連ツールが含まれていて、お得ですよ。
フレームレート指定コンポーネントTargetFPS.cs
WebGLで出力したいゲームの多くは、カジュアルなゲームなので60fps以上の高フレームレートは不要です。
今回紹介したコンポーネントをシーンに置いておけば、60fpsや30fpsに簡単に設定できて便利です。
例えば起動時のローディングシーンでは30fpsにしておき、ゲームが始まったら60fpsにしたりできます。
また、アプリ実行中もInspectorから動的にFPSを変えられるのでデバッグでも重宝しています。
例えば、フレームレート低下時のバグやプレイ感を確認するのもInspectorから5fpsや10fpsに指定するだけです。
いままで次のようなバグの解決や、修正確認に役立ってきました。
- 低フレームレートで、移動が遅くなる不具合
- 同一フレームに複数ボタンを押したときの不具合
- タブ切り替えボタンを押下後、タブ切り替え中アニメ中に決定ボタンを押したときの不具合
ということで、ゲームでよく使うコンポーネントの改修と紹介の話でした。
-
前の記事
AIで短編小説作ってみた!プロンプト付き 2023.05.13
-
次の記事
UnityroomでAddressablesを使おう! 2024.09.14