概要
ゲーム開発において、「面白いゲームを作ること」と同じくらい重要なのが、「快適に動作するゲームを作ること」です。フレームレートの低下(カクつき)や、メモリの使いすぎによるクラッシュは、プレイヤーの体験を著しく損ないます。こうしたパフォーマンスの問題を解決するためには、まず「何が、どこで、なぜ重いのか」という原因を正確に特定する必要があります。そのための最も強力なツールが、Unityに標準で搭載されているProfilerです。
Profilerは、ゲーム実行中のCPU使用率、メモリ確保、レンダリング処理、物理演算など、パフォーマンスに関する様々なデータをフレーム単位で収集し、グラフや詳細なリストで視覚的に表示してくれます。これにより、開発者は推測ではなく、データに基づいてボトルネックを特定し、的を絞った最適化を行うことができます。
この記事では、Profilerの基本的な使い方と、よくあるパフォーマンス問題を発見するための主要なモジュールの見方について解説します。
Profilerの基本的な使い方
-
Profilerウィンドウを開く: メニューから
Window > Analysis > Profilerを選択してProfilerウィンドウを開きます。 -
プロファイリング対象の選択: ウィンドウ上部の
Playmodeドロップダウンで、プロファイリング対象を選択します。Editorを選択するとUnityエディタ内で実行されているゲームを、Enter IPやUSB接続したデバイス名を選択すると、実機(PC、モバイル、コンソール)で実行されている開発ビルドをプロファイリングできます。正確なパフォーマンスを測定するには、必ずターゲットとなる実機でプロファイリングを行うことが重要です。 -
記録を開始:
Recordボタンがオンになっていることを確認し、ゲームを再生します。すると、各モジュールのグラフがリアルタイムで更新され始めます。 -
フレームの選択と分析: グラフ上でスパイク(突出した山)が発生しているフレームや、特に処理が重そうなフレームをクリックすると、そのフレームにおける処理内容の詳細がウィンドウ下部に表示されます。ここで、どのメソッドの呼び出しに何ミリ秒かかっているか、といった具体的な情報を掘り下げていくことができます。
主要なプロファイラモジュール
Profilerウィンドウの左側には、分析したい項目に応じたモジュールが並んでいます。
CPU Usage (CPU使用率)
最もよく使われるモジュールです。各フレームでCPUがどのような処理に時間を費やしたかを示します。
- Timeline View: 各スレッド(Main Thread, Render Threadなど)の処理が時系列で表示されます。どの処理が全体のフレーム時間を押し上げているかの概要を掴むのに役立ちます。
- Hierarchy View: フレーム内のすべてのメソッド呼び出しが階層的に表示されます。
Time msやSelf ms(そのメソッド自体の処理時間)でソートすることで、最も時間のかかっている処理を特定できます。- よくあるボトルネック:
Update()内で重い処理を毎フレーム実行している、GetComponent()をループ内で呼び出している、複雑な物理演算、非効率なAIロジックなど。
- よくあるボトルネック:
GPU Usage (GPU使用率)
GPUがどのような描画処理に時間を費やしたかを示します。GPUがボトルネックになっている場合(GPU Bound)に役立ちます。(一部のプラットフォームでのみ利用可能)
Rendering (レンダリング)
CPUがGPUに対してどのような描画命令を出しているかを示します。
- Batches (バッチ数): ドローコールの回数。これが多すぎるとCPUの負荷が高まります。マテリアルを共有するなどして、スタティックバッチングやダイナミックバッチングが効くように最適化することが重要です。
- SetPass Calls: シェーダーやマテリアルの切り替え回数。これもCPU負荷の原因となります。
- Triangles / Vertices: シーン内に表示されているポリゴン数・頂点数。これが多すぎるとGPUの負荷が高まります。
Memory (メモリ)
ゲームがどれだけのメモリを確保・使用しているかを示します。
- Simple View:
Total Reserved Memory(予約済み合計メモリ)やUnity(Unityエンジンが使用するメモリ)などの概要を確認できます。 - Detailed View:
Take Sampleボタンを押すことで、その瞬間にメモリ上に存在するすべてのアセットやオブジェクトのスナップショットを取得できます。どのテクスチャが、どのメッシュが、どのオーディオクリップがメモリを圧迫しているかを特定するのに非常に強力です。テクスチャの解像度が高すぎたり、圧縮設定が不適切だったりすることがよくある原因です。
GC (Garbage Collection)
CPU Usageプロファイラで、GC.Collectという項目が大きなスパイクとして現れることがあります。これはガベージコレクション(GC) が 発生したことを意味します。GCは、不要になったメモリを自動でクリーンアップする便利な仕組みですが、その処理中はゲームが一時的に停止(Stutter)するため、プレイヤーにカクつきとして体感させてしまいます。
GCの主な原因は、Update()内での不要なメモリ確保(アロケーション)です。例えば、
- 文字列の結合 (
string a = "hello" + "world";) newキーワードによるクラスのインスタンス化- 配列の新規作成 (
new Vector3[10])
などを毎フレーム行うと、小さなゴミが大量に発生し、GCが頻繁に走る原因となります。ProfilerのGC Alloc列に注目し、毎フレームメモリを確保している処理を特定して、可能な限り削減することがGCスパイクを抑える鍵です。
まとめ
Profilerは、パフォーマンス最適化における「聴診器」や「レントゲン」のようなものです。
- 推測で最適化しない。必ずProfilerで計測し、データに基づいてボトルネックを特定する。
- 正確な計測のため、可能な限り実機でプロファイリングを行う。
CPU Usageモジュールで、時間のかかっているメソッドを特定する。Renderingモジュールで、バッチ数やポリゴン数を確認する。Memoryモジュールで、メモリを圧迫しているアセットを特定する。GC Allocに注目し、不要なメモリアロケーションを削減してGCスパイクを防ぐ。
パフォーマンス最適化は地道な作業ですが、Profilerを使いこなすことで、効率的に 問題を発見し、プレイヤーに快適なゲーム体験を届けることができます。