敵が増えた場面で動きが重くなった。stat unit を見るとGameの時間が長い。ゲーム側の処理から調べたいものの、AIなのか、毎フレームの検索なのかまでは分からない。そんなときに使うのが Unreal Insights です。
ゲームを動かしたときの処理を記録し、後から「この時間帯には何をしていたか」を調べられます。数字を見逃さないよう画面を睨む代わりに、気になる瞬間へ戻り、時間を使った処理を探せます。
この記事では、まず短い記録を開くところから始めます。その後、時間軸と集計の読み方を覚え、同じActorの検索を毎フレーム繰り返す小さな例で、変更前後を比べます。
この記事でわかること
- トレースを記録し、保存したファイルを開く手順
- Blueprint名を記録する設定と、見つからないときの確認
- 処理の入れ子、Inclusive・Exclusive、呼び出し回数の読み方
- 記録から候補を絞り、必要な動作を保って修正する流れ
Windows版UE5を想定し、Blueprintの変数・関数・ノード接続を使います。stat unitの記事で扱った、同じ場所・画質・FPS上限で比べる考え方も使います。図はブログ用の模式図で、計測値は説明用の例です。
Insightsは、何を記録する道具か
トレース は、処理の開始・終了などを時刻とともに残した記録です。Unreal Insightsでは、その記録を時間軸や一覧表にして読みます。録画映像ではなく、ゲームが内部でどんな仕事をしていたかを見るためのものです。
| 道具 | 最初の使いどころ |
|---|---|
| stat unit | 実行中の時間を見て、Game・Draw・GPUなど調べる担当を絞る |
| Unreal Insights | 問題が起きた時間帯へ戻り、記録された処理とその内訳を調べる |

Insightsの帯一つが、記録された処理の区間です。これを タイミングイベント と呼びます。同じ種類のイベントをまとめて集計する名前は タイマー です。Blueprintで「一定時間後に実行する」Timerとは、ここでは別の意味です。
すべての関数やBlueprintノードが自動で記録されるわけではありません。有効にした記録項目と、エンジンやコードに用意された計測の範囲が見えます。見つかった名前は調査の手がかりにし、修正前後の比較まで進めましょう。
まず短いトレースを記録して開く
最初は、手元のThird Personなどのプロジェクトで、数秒分を保存できれば十分です。記録するゲームと保存先がはっきりするよう、ここではStandalone Gameへ起動引数を渡します。
起動引数 は、ゲームを立ち上げるときに渡す追加の設定です。プレイ中のコンソールへ入力する命令とは、入力する場所が違います。
1. 保存先と記録項目を指定する
エクスプローラーで、記録を置くフォルダを作ります。以下は C:/UETraces を使う例です。別の場所に作った場合は、引数のパスも合わせてください。
「Edit → Editor Preferences → Level Editor → Play」を開き、「Play in Standalone Game」の Additional Launch Parameters に次を入れます。既存の設定はメモしておき、関係のない引数は残します。すでに同じ名前の引数がある場合は、重複させず今回の値へ変更してください。
-trace=cpu,frame,bookmark,AssetLoadTime -statnamedevents -tracefile="C:/UETraces/insights-test.utrace"
| 指定 | 今回の役割 |
|---|---|
cpu | CPUの処理区間を記録する |
frame | フレームの区切りを記録する |
bookmark | 時間軸へ目印を残せるようにする |
AssetLoadTime と -statnamedevents | Blueprint名を含む、追加の名前付き計測を有効にする |
-tracefile=... | 記録を保存するファイルを指定する |
cpuやframeのように、-trace= の後ろへ並べる記録項目を チャンネル と呼びます。CPUの大まかな調査はcpuとframeから始められますが、今回はBlueprint名も調べたいので、追加の設定を入れています。

AssetLoadTimeという名前はアセットの読み込みを連想させますが、公式のBlueprint名の記録手順でも使われます。-statnamedevents だけを追加して終えず、組み合わせて指定してください。
2. Standaloneで動かし、記録を止める
- 「Play」のメニューで Standalone Game を選んで起動します。
- 読み込みが落ち着いたら、数秒歩くなど、普段の操作をします。
- ゲームのコンソールへ
Trace.Statusと入力し、記録状態と有効なチャンネルを確認します。 Trace.Stopと入力して記録を止め、ゲームを終了します。- 指定したフォルダに
insights-test.utraceができたことを確認します。
コンソールの開き方はstat unitの表示手順と同じです。.utrace はトレースのファイル形式です。ファイルが作れたら、記録する側の準備はできています。
同じ名前を使い続けると前後の記録を取り違えやすいため、本番の比較では before.utrace、after.utrace のように分けます。
3. Unreal Insightsで開く
エディタ下部の「Trace」メニューから Unreal Insights(Session Browser) を開きます。Windowsでは、使用中のエンジンの Engine/Binaries/Win64/UnrealInsights.exe を直接起動しても構いません。
Session Browserは、記録を選ぶ最初の画面です。「Open Trace」の横の矢印から「Open File」を選び、保存した .utrace を開きます。エクスプローラーからこの画面へファイルをドラッグしても開けます。解析が進むと、処理時間を調べる Timing Insights が表示されます。
エディタ側のTraceメニューにも「Start Trace」「Stop Trace」があります。エディタ自身を測るときには便利ですが、別に起動したStandaloneの記録と混同しないでください。今回の手順では、ゲームへ渡した引数で記録しています。
Blueprint名が記録できたかを先に確かめる
Timing上部の時間目盛りをドラッグし、実際にプレイした範囲を選びます。Timers一覧で、動かしたBlueprint名の一部を検索してください。たとえばThird Personなら BP_ThirdPersonCharacter、後半の実践なら BP_SearchProbe が候補です。末尾に _C などが付く場合もあります。各パネルの読み方は次の節で整理します。
表示される名前や細かさは、UEの版・処理・設定で変わります。Get All Actors Of Class というノード名まで一段ずつ表示される、と期待する必要はありません。
| 見つからないとき | 確認すること |
|---|---|
| CPUの帯自体がない | cpuを記録したか。CPUトラックを非表示にしていないか |
| エンジン名はあるがBlueprint名がない | AssetLoadTimeとstatnamedeventsが、測るゲームへ渡っているか |
| 名前の検索が空になる | 対象が動いた時間を選んだか。検索や表示フィルタを絞りすぎていないか |
| 前の設定の記録を開いていた | 出力先とファイル名を確認して、短く取り直す |
記録に入っていない名前は、後から帯を深くたどっても現れません。短い試し撮りで準備を確認してから、重い場面の調査へ進みます。
Timing Insightsで、調べる時間を選ぶ
画面には多くの項目がありますが、最初は三つを押さえます。パネルの配置は変えられるため、名前で探してください。
| パネル | 何を見るか |
|---|---|
| Frames | フレームごとの長さ。高い棒は時間がか かったフレーム |
| Timing | GameThreadなどの行に並ぶ、処理の帯と入れ子 |
| Timers | 選択した時間内の、同じ種類の処理の回数・合計時間 |

GameThreadはゲームを進めるCPUのスレッドです。トラック は、こうした担当ごとに処理を並べた行を指します。横方向が時刻、帯の横幅がその区間にかかった時間です。
「一番高い棒」より、問題が起きた場面を選ぶ
敵が出た瞬間だけ止まるなら、その瞬間と前後を見ます。ずっと重いなら、読み込み後の通常プレイを数秒選びます。起動直後やコンソールを開いた瞬間が最長でも、それが今回調べたい問題とは限りません。

- Framesの気になるフレームをクリックします。複数なら、最初をクリックし、最後を
Shift+クリックします。 - Timing上部の時間目盛りをドラッグしても、範囲を選べます。
Fで選択範囲を見やすい幅へ拡大し、必要ならマウスホイールで調整します。- GameThreadなど 、調べる担当の帯にマウスを置き、名前と所要時間を読みます。
範囲を変えるとTimersの集計も変わります。表の「合計12ms」が1フレーム分なのか、5秒分なのかは、選択範囲とセットで判断します。
入れ子と集計から、処理の内訳を読む
同じトラックの中で、ある帯の下へ収まるように描かれた帯は、その処理の内側で行われた仕事を表します。上が親、下が子です。別のスレッドの行と上下に並んでいるだけなら、親子とは限りません。
親と子の時間を、二重に足さない
たとえば親の処理が12ms、その中で呼んだ子の処理が8msなら、子を除いた残りは4msです。
| 表示 | 意味 | この例 |
|---|---|---|
| Inclusive(Incl) | 子の処理も含めた時間 | 親は12ms |
| Exclusive(Excl) | 記録された子の時間を除いた残り | 親は4ms |

親12msと子8msを足して、合計20msとは数えません。親のInclusiveが大きくても、その大半が子なら、子の内訳を調べます。Exclusiveが大きい場合は、その区間のコードや、まだ細かく記録されていない処理を確認します。
待ち時間が長い帯もあります。幅が広いという理由だけで、その関数の計算を軽くすれば速くなるとは限りません。
長い一回と、短い処理の繰り返しを分ける
Timersでは、所要時間だけでなく Count(回数) も見ます。一回0.05msでも、選んだ範囲で200回なら合計10msです。これは読み方の例で、特定のActorの実測値ではありません。

CountはActorの個数ではなく、選択範囲内で記録されたイベントの回数です。一体が何フレームも呼ばれた分や、同じ種類の複数Actorの分が合わさることがあります。
Timersに集計モードがある版では、まずInstanceを選び、Countと合計時間を読みます。Game Frameなどのモードでは1フレームあたりの集計になるため、列の説明も確認してください。
呼び出し元と、呼び出し先をたどる
気になるタイマーを選ぶと、Callers では「誰が呼んだか」、Callees では「そこから何を呼んだか」を調べられます。こちらは選択範囲の集計をツリーで見せるパネルです。
Timingの帯をクリックすることと、ツリーの枝を展開することは別の操作です。「帯を開き続ければ自分のBlueprintに必ず着く」と考えず、時間・回数・親子の内訳を組み合わせて候補を探します。
実践:毎フレームの検索を減らして比べる
同じ種類のActorが何個あるかを数える、小さな実験を作ります。今回は、開始後にActorが増えたり減ったりしないレベルです。毎フレーム数え直す状態と、開始時に一度数える 状態を比べます。

1. 一個で、数が読めるところまで作る
Third PersonのBlueprintプロジェクトで、Actorを親にした BP_SearchProbe を作ります。見つけやすいようStatic Mesh Componentを追加し、Engineの基本形状Cubeを指定してください。Collision PresetsはNoCollision、Simulate PhysicsとCast Shadowはオフにします。
Integer変数 FoundCount を作り、初期値は0にします。次に、入力・出力を持たない関数 RefreshPeerCount を作り、次の接続を用意します。
- 関数の実行出力 → Get All Actors Of Classの実行入力。
- Actor ClassでBP_SearchProbeを選択。
- Out Actors → 配列のLength。Lengthは配列に入った要素数を返します。
- Get All Actors Of Classの実行出力 → Set FoundCountの実行入力。
- Lengthの値 → Set FoundCountの値。

Get All Actors Of Classは、指定クラスのActorを集めるノードです。BP_SearchProbeが一個だけなら、自分自身も含めて結果は1個です。対象が多いほど集める仕事も増えるため、同じ検索を頻繁に繰り返す必要があるかを考えます。
Event Graphでは、まず Event BeginPlay → RefreshPeerCount → Print String をつなぎます。FoundCountのGetから「To String (Integer)」へつなぎ、その文字列をPrint StringのIn Stringへ渡してください。数字のピンをIn Stringへ直接つなぐと、変換ノードが自動で入る場合もあります。Durationは5秒程度にします。

別の経路として、Event Tick → RefreshPeerCount をつなぎます。こちらにはPrint Stringを付けません。開始時に一度表示し、プレイ中は数え直すだけにします。

Class DefaultsのActor TickでStart with Tick Enabledをオン、Tick Intervalを0にします。Compileしてレベルへ一個置き、Playして「1」が出れば、検索と保存はできています。
2. 同じActorを増やし、変更前を記録する
Stopし、BP_SearchProbeをAlt+ドラッグで複製します。まず32個程度から始め、必要なら128個、256個へ段階的に増やします。複数選択した一組をまとめて複製しても構いません。
開始時には各Actorが個数を一度表示します。表示が消え、読み込みが落ち着いてからの時間 を調査対象にします。計測中にPrint Stringを毎フレーム呼ばないことも確認してください。
200個なら必ずGameが何msになる、という条件ではありません。個数による差が小さいPCでも、記録の取り方と呼び出しの変化は練習できます。
先ほどの起動引数のファイル名を before.utrace に変え、Standaloneで起動します。同じ開始位置で動かず、通常プレイ部分を約5秒残してから Trace.Stop で止めます。全チャンネルや画質、FPS上限は前後で揃えます。
3. 検索に関わる処理を探す
記録を開き、起動直後を避けた5秒程度を選びます。Timersの検索欄で BP_SearchProbe や RefreshPeerCount の一部を探し、GameThreadの帯、Count、Inclusive・Exclusiveを確認します。
Blueprint名がまとまったタイマーで表示される場合もあります。その中身をBlueprintで確認し、今回繰り返している検索を調査候補にします。ノード名が出ないことだけを理由に、記録失敗と判断しないでください。
4. 一度だけ数える形にして、再計測する
BP_SearchProbeのClass Defaultsで Start with Tick Enabledをオフ にします。BeginPlayの経路は残し、Actorの個数と配置も変えません。Compileして保存します。
これで、開始時には同じ個数を数えて表示し、その後は同じ検索を繰り返さなくなります。今回の「開始後に個数が変わらない」という条件では、保存した数もそのまま使えます。
ファイル名を after.utrace に変え、同じ条件で記録します。変更前と同様、起動直後を避けた約5秒を選んで比べてください。
| 確かめるもの | 比較のポイント |
|---|---|
| BeginPlayの表示 | 前後で同じ個数になっているか |
| 通常プレイ中の帯 | Tick由来の繰り返しが減ったか |
| 同じタイマーの集計 | 同じ長さの範囲で、回数や合計時間が減ったか |
| フレーム時間 | 全体も改善したか。ほかの処理や上限に制限されていないか |

Tickを止めた後は、選んだ通常プレイ区間から対象のタイマー自体が消える場合もあります。開始時の表示で動作を確認でき、変更前には同じ設定で記録できていたなら、繰り返しがなくなった結果として読めます。
必要ならTickをオンへ戻して記録を取り、元の傾向へ戻るかも確かめます。単に見つかった名前を「原因」と呼ぶより、変更と結果の関係がはっきりします。
実際のゲームで敵が増減するなら、開始時に一度数えるだけでは情報が古くなります。敵の生成・撃破時に数を更新するなど、必要な動作を保つ修正にします。TickとTimerの使い分けも、その頻度を決める参考になります。
Memory Insightsは、メモリを調べる入口
処理時間がmsなら、メモリはデータを置く容量の話です。確保 は置き場所を用意すること、解放 は使い終えた場所を返すことです。Memory Insightsでは、いつ確保され、どの時点まで残っているかを調べます。
メモリ確保・解放の追跡は、プロセスを起動する時点からmemoryを有効にする 必要があります。通常のCPU調査とは別の記録にします。
Developmentでパッケージ化したゲームのショートカットを作り、「プロパティ → リンク先」の実行ファイルの後ろへ、空白で区切って次を付けます。保存先フォルダは先に作っておきます。
-trace=default,memory -tracefile="C:/UETraces/memory.utrace"
ゲームを起動して調べたい操作を行い、Trace.Stopで止めた記録を開きます。InsightsのメニューからMemory Insightsへ進むと、時間ごとの確保量などを確認できます。

最初は「レベルに入る前」と「入った後」で、残っているメモリがどう変わるかを見ると目的を絞れます。増加だけで解放漏れとは限りません。次に使うためのキャッシュや、意図して保持するデータもあります。
アセット名・クラス名で分けたい場合は metadata,assetmetadata も追加します。関数名まで読むには、ビルドに対応するデバッグ情報が必要に なる場合があります。詳しい読み方は公式Memory Insightsへ進み、参照によって不要なアセットまで読まれている場合はソフト参照と非同期ロードを検討します。
おまけ:先に知っておくと良いこと
記録自体にも負荷がある
チャンネルや名前付きイベントを増やすと、記録する仕事も増えます。まず短く取り、調べる目的に合わせて追加します。変更前後では記録設定も揃え、最後に記録なしの通常プレイでも動作を確かめてください。
自分の名前がなくても、分かることはある
描画の待ち、アセットの読み込み、ほかのスレッドの処理が関係することもあります。空白や長い待ちが見えた場合も、Blueprint名が出るまで無理に掘り続けず、どの担当を待っているかへ調査を切り替えます。
記録と条件を一緒に残す
ファイル名だけでなく、Actor数、画質、解像度、上限、変更内容、選んだ時間帯をメモします。記録ファイルの容量は期間とチャンネルで変わるため、必要な前後比較を残して整理します。
実験後はAdditional Launch Parametersをメモしておいた元の設定へ戻し、変更したFPS上限なども戻します。配布する環境での最終確認には、Developmentビルドを対象PCで動かして記録します。
次に重い場面へ出会ったら、「どの名前が怪しいか」の前に、どの時間を調べるのかを決めてみてください。場面と内訳、変更前後の三つを揃えると、数字から次の修正を考えや すくなります。
まとめ
- トレースは「記録して、あとからファイルで読む」道具
- Blueprint名を残す設定をしないと、どの処理か分からない
- Inclusiveは中身を含めた時間、Exclusiveはその処理だけの時間
- 呼び出し回数が多いものは、1回を速くするより回数を減らす
見る前の問いかけは、「太いのは1回が重いからか、回数が多いからか」 です。そこで直し方が変わります。
まず全体を掴むなら statコマンド、毎フレームの処理を減らす例は Tickを使わない設計 にあります。
参考:Trace、Command-Line Arguments、Timing Panel、Timers and Counters、Insights Reference。