[Unity] 開発中にFPS維持できなくなって、原因よくわからないとき(超初学者向け)

パフォーマンスチューニング以前の問題みたいな部分。
本格的にやるには、もっともっとつっこむべき部分が多くあるはず。

「なにもしてないのに重くなった!」みたいな気分になったときに
まず、チェックしてみるといいかもしれないところや、
見た目上、特に問題なさそうだけど、現状のパフォーマンスの状況を知りたいとき
の確認方法、をいくつかメモ。

現状を調べてみる

1. まずはStatistics

Gameビューの右上の Stats というボタンを押すと表示されます。

下記の値を確認することができます。(一例)

FPS: 現在のFPS(Frame Per Second)
Batches: DrawCallの総数
Saved by batching: ドローコールバッチングで統合されたドローコールの数
Tris : 描画する三角形ポリゴンの数
Vert : 描画する頂点数
Screen : 描画されている画面サイズ数と、そのためのメモリ使用量
Animations : 再生しているアニメーションの数

ここで確認できる値から、方針としては

FPSは可能な限り維持しつつ(30-60FPS)他の値は
より小さいほうがパフォーマンスが出る、ということが言えます。

更に、Screen(画面解像度)は、パフォーマンスのために小さくしたり
するのは、難しいので、こちらも維持したい(例えば1920×1080)

となると、

  • Tris,Vertを小さくしたい
    • モデルをローポリゴンに変更する
    • 表示モデルの数を少なくする
    • LOD(Level of Detail)設定する
    • 遠くはローポリ、近くではハイポリにオートで切り替える機能
    • Tessellation頑張る
    • 動的なポリゴン分割
    • 僕は自分でシェーダー書いたことないですが、機能としてはLODに似てる
    • DirectX11世代で利用可能
  • Animationsを小さくしたい
    • AnimatinonやAnimatorControllerの使用を減らす
    • 決まった動きを繰り返すだけ、とかならシェーダーでアニメーションさせる、など
  • Batchesを小さくしたい
    • これは上記の他の値を含むたくさんの要素が関係してるので一概には言えないが、まずはドローコールバッチングでまとめられるものを、できるだけまとめる。 -> 可能な限り共通のMaterialを利用する、もしくはハードウェアインスタンシングを自分で頑張る
    • SpliteやPerticleSystemでテクスチャアトラスを利用する など

Unity レンダリング統計ウィンドウ

2. Profilerで見てみる

Statisticsのざっくりした数値だけだと、大量に存在する
Scene内のどの部分がボトルネックになっているか、わかりづらい場合があります。

そのときはより、詳細を確認できるProfilerを使ってみましょう。
Statisticsで表示されている、最終的な数字だけでなく、CPU負荷、
メモリ、レンダリングや物理演算の処理時間等が確認できます。

たとえばCamera.Renderが全体の処理時間の多くを利用していた場合
ポストエフェクト等を見なおしたりするための動線になったりします。

3. FrameDebuggerを使ってみる

ProfilerでCamera.Renderの処理にたくさんの時間がかかってる、とわかった
として、それが複数のエフェクトをかけていたときに
どのエフェクトがより、ボトルネックになっているかを確認するのに、
FrameDebuggerが便利です。

特定のフレームでサスペンドし、そのフレームでの処理時間や
レンダリング結果をかなり詳細に確認することができます。

なにか重いなー。。。と思ったらStatisticsでアタリをつけ
Profilerでざっくりと箇所を特定、FrameDebuggerで
詳細を確認しつつチューニング、という流れがいいのかな?

4. おまけ 正確なFPSを出してみる

StatisticsでリアルタイムなFPSを確認することができることは
前述しましたが、実はガタツキが激しく、正確な値ではないことが
あります。

そのため、自前でUpdateメソッドが1秒後ごとに何回呼ばれているか、
を確認することで正確なFPSを取得している方もいらっしゃいました。(参考リンク参照)
(名前を忘れてしまったんですが、AssetsStoreとかにも同様のものがあるらしい)

参考リンク

よくわからないときにチェックしてみると解決するかもしれないポイント

1. GameビューとSceneビューを同時に画面出力している

なーんか、特に変更とかしてないのに急にFPS落ちたなー、って時がありました。
前述の色々を試して、なにが重いのか調べてたんですが、一向にわからず。

先輩に相談してみたところ、実行してGameビューを動かしながらSceneビューで
オブジェクトを確認していたことが原因だとわかりました。

考えてみれば当然なんですが、実行中はGameビューはもちろん
Sceneビューもダイナミックに動くので、そちらにPCのリソースがとられれば
動作が重くなります。

デュアルディスプレイで作業しているので、2枚目のディスプレイに
Gameビューを、メインのディスプレイにSceneをいつも表示して
いましたが、実行中はSceneは表示しないほうがパフォーマンスが出ます。

2. AnimatorControllerを多用している

単純に重いです。たくさんInstantiateされた時点でStateMachineが
動作するより、適宜アタッチしたほうがいい、かも

3. PerticleSystemを多用している

いっぱい使うともちろん重いです。パーティクルの数が多いとより負荷が
高くなります。一定以上はComputeShaderを利用する等したほうが
いいかもしれません。

4. OnGUIを多用している

内部的な詳しい仕組みはわかっていませんが、OnGUIを一回呼び出すと
DrawCallが二回呼ばれます。

その他、Scriptでマテリアルを代入したときは、暗黙的にコピーされ、DrawCallが増えます

5. QualitySettingsでAnti Aliasingが有効になっている

UnityではデフォルトでQualitySettingsのAntialiasが
2x Multi Samplingで有効になっています。

が、これがじわじわ重いときがあります。
そして、CameraがHDR有効になっていると、このAntialiasは
利用できないらしいので、不要であればきっちゃっていい、かも

参考リンク

[Unity] 開発中にFPS維持できなくなって、原因よくわからないとき(超初学者向け)」への1件のフィードバック

  1. ピンバック: パフォーマンス・チューニング – コドモのころの夢

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です