【Unity】プロファイラーでリソースの使用状況をチェックしよう
高負荷な処理をしていると唸りを上げるPCのファン。計算量が多くなってCPUが熱を持っているので、一生懸命冷まそうとしてくれています。冬の朝に作業を開始すると、こうしたPCの排熱で手を温めるデベロッパーがいるとかいないとか。このページではそんな負荷に関する話を。
Unityでゲームを作っていると、「あれ? なんだか処理が重いな?」と感じることもあります。Updateの中に重い処理を書いていたりするとゲームの動きがカクカクして重力を感じます。
初心者の頃はUpdateの中でGetComponentしてたり、foreachがいくつも回っていたりしたので、やたらと処理が重くなっていた記憶があります。
こうした原因を特定するために、UnityではProfiler(プロファイラー)の機能が提供されています。各フレームのCPUの処理時間などもメソッド毎に確認できるので非常に便利です。
環境
macOS Catalina 10.15
Unity2019.4.4f1
参考文献
公式のマニュアルでのプロファイラーの解説もぜひご覧ください。Unity2019.4のマニュアルだと英語になっていたので、日本語化されているUnity2018.4のページにリンクを貼っています。
テラシュールブログさんのプロファイラでパフォーマンスを改善する記事が勉強になります。
CPUの負荷
CPUに負荷がかかっているということは、それだけ処理時間が長くなっているということ。CPUの処理時間の長さはゲームで大切なフレームレートにも関連してきます。
例えば60FPSのゲームであれば、1フレームの処理にかけられる時間は約16.67ms(ミリ秒)で、この時間を超えると本来次のフレームが描画される時間に食い込んでしまいます。
これはいわゆる「処理落ち」で、ゲームを遊んでいるとよく見かけます。
たまーに発生するくらいならプレイヤーの立場でもそこまで気にしませんが、目に見えて何度も発生すると「調整頑張って!」と言いたくなることも。
処理時間を調整するなら、まずはどんな処理に時間がかかっているかを知る必要があります。
Profiler(プロファイラー)を使おう!
Unityでは「Profiler(プロファイラー)」の機能があり、この機能でどんな処理に時間がかかっているかなどを知ることができます。Profilerウィンドウを開くには、Projectウィンドウなどの右上にあるメニューボタンをクリックし、[Add Tab] -> [Profiler] を選択します。
下の画像はプロファイラーウィンドウの例です。
この画像ではCPU Usage(CPUの使用量)を表示させています。左側の領域では「Rendering」「Scripts」など、処理内容に応じて色分けされた凡例が表示されており、クリックすると右のグラフへの表示/非表示を切り替えることができます。特定の領域、例えばスクリプトの処理を中心に確認したい場合はこの部分を使って切り替えると便利。
右側のグラフエリアでは横軸に経過時間(フレーム単位)、縦軸にCPUの使用量が領域毎の積み重ねで表示されます。Unityエディタでゲームを実行している場合はUnityエディタの処理についてもここに含まれて表示されるので、「あれ? ビルドしたら案外パフォーマンスいいな?」なんてことも。
このグラフエリアでクリックすると、その位置のフレームでどれくらい処理に時間がかかったのかを表示してくれます。グラフ内に代表的な値を表示する他に、プルダウンで「Hierarchy」を選択している場合はウィンドウ下部にどんな処理でどれだけ時間がかかったのかを表示してくれます。
「Overview」の列では処理内容が表示されます。「Time ms」の列でソートしておくと時間のかかった処理から順番に表示してくれるので、時間がかかった処理の内容を確認してスクリプトを修正する流れが簡単になります。画像では意図的に重い処理を走らせているのでひどい処理時間になっていますが、60FPSを目指すなら16.67ms以内、30FPSを目指すなら33.33ms以内に処理が完了するように調整すると良いでしょう。
ちなみにこの画像を撮影するために実装した重い処理は「毎フレームforループを1000回実行してその中でDebug.Logでコンソールに出力する」というものです。Debug.Logは結構重たい処理なのでこれを使って処理時間を増やしていました。
リリースするゲームをビルドする際は、デバッグの行をコメントアウトするかPlayer SettingsでDebug.Logの出力を抑制するとパフォーマンスが向上するかもしれません。
タイムライン表示も
「Hierarchy」の階層表示の他に、「Timeline」として時間軸に沿ったCPU時間を表示することもできます。
スレッドごとにどれくらいの時間を使っているのかを確認できます。特に意識していなければUnityではシングルスレッドで動作しますが、C# Job Systemなんかを使っている場合はタスクの振り分けの状況なんかもここで確認できます。画像だと折りたたんでいる「Unity Job System」を開くとワーカーごとの処理時間を確認することができます。
メモリの確認も
CPUと同様に、メモリの使用率が大きいなら大きいテクスチャが読み込まれていないかなどを確認すると良いでしょう。
プロファイラーだとUnityエディタが使っているメモリも入っていたりするので、もしメモリの使用量をより正確に知りたいならiOSビルドしてXcodeで確認するのが簡単です。
メモリを多く使うのはテクスチャやオーディオなので、この辺りの数と容量がどれくらいになっているかの目安を把握するのには便利だと思います。
上の画像は「Simple」なものでしたが、詳細に確認する場合は「Deteiled」に切り替えることもできます。
「Deteiled」の場合はリアルタイムに状況を表示するというよりは、特定のフレームでキャプチャしてその内容を表示するイメージです。「Deteiled」のプルダウンの右側にある [Take a Sample Playmode] のボタンをクリックすることでキャプチャを行うことができます。すると以下のように階層表示でメモリの使用量を表示してくれます。
上の画像では「Scene Memory」の項目を開いていて、シーン内のオブジェクトなどが使用しているメモリを表示してくれています。サンプルを取得したシーンではCubeオブジェクトを自動的に生成して配置する処理を行っているので、「Cube (Clone)」が200個くらい生成されています。オブジェクト1つあたり0.6KBのメモリを使っていて、それが200個となると約120KBとなります。表示内容とぴったりです。
テクスチャなどのアセットが使っているメモリに加えて、スクリプトで操作しているオブジェクトのメモリ割り当ても調べておくとよりパフォーマンス調整しやすくなるかなーと思います。
CPU、メモリあたりはうまく調整しておくと快適なゲームプレイが提供できるので、チェックする癖をつけておくといい感じです。
まとめ
Unityでパフォーマンスを確認するならProfiler(プロファイラー)を使いましょう。
自分の書いたコードと実際のパフォーマンスを比較することで、「あ、この書き方だと処理に時間がかかるな」「このタイミングでいらないアセットをアンロード(メモリ上から破棄すること)しておこう」なんて感じでなんとなく掴めてくるので、自分で処理を書いたらプロファイラーを確認する癖をつけておくと良いと思います。
ゲーム開発の攻略チャートを作りました!
-
前の記事
テストでよく聞くブラックボックスとホワイトボックスの話【ゲーム開発】 2020.10.29
-
次の記事
ひとりブレインストーミングでアイディアのタネをストック【ゲーム開発】 2020.10.31
コメントを書く