9.

UE5でFrameGrabberを使う方法|ブループリントでの画面取得とSceneCapture2D代替

編集

Unreal Engine 5(UE5)のFrameGrabberは、レンダリング結果(描画フレーム)をキャプチャするためのC++向けの仕組みであり、ブループリント(Blueprint)から直接呼び出せる標準ノードは用意されていません。そのため「ブループリントだけで画面フレームを取得したい」場合は、FrameGrabber自体を使うのではなく、Scene Capture 2D+Render Targetハイレゾスクリーンショット用のコンソールコマンド、あるいはFrameGrabberをC++でラップしてBPノードとして公開する、のいずれかを選ぶのが現実的です。この記事では、それぞれの違いと、ブループリント中心で画面を取得する具体的な手順を解説します。

この記事の要点
  • FrameGrabber(FFrameGrabber)はC++のクラスで、MovieSceneCaptureモジュールに含まれる。BP標準ノードは存在しない。
  • ブループリントだけで画面を取りたいなら、Scene Capture 2D+Render Targetコンソールコマンド(高解像度スクリーンショット)を使うのが定番。
  • FrameGrabberの低レイテンシなフレーム取得が必要なら、C++で実装し、カスタムノード/カスタムイベントとしてBPへ公開する。
  • 用途によって最適解が変わる。動画化・リアルタイム転送はC++寄り、ミニマップ・サムネイル・スクリーンショット程度ならBPの代替手段で十分。

FrameGrabberとは

FrameGrabberは、ビューポートに描画されたレンダーターゲット(フレームバッファ)の内容を、効率よくCPU側へ取り出すための仕組みです。実体はC++のFFrameGrabberクラスで、エンジンのMovieSceneCaptureモジュールに含まれています。内部的には複数の解像度サーフェスを使い回し、レンダースレッド側で描画結果を解決(resolve)してから取得するため、毎フレームのキャプチャでも描画を待たせにくい設計になっています。

主なメソッドは次のとおりです(いずれもC++から呼び出します)。

// FFrameGrabber の主なメソッド(C++、MovieSceneCapture モジュール)

StartCapturingFrames(); // キャプチャ開始

CaptureThisFrame(Payload); // このフレームをキャプチャ対象としてキューに積む

GetCapturedFrames(); // 取得済みフレームを受け取る(FCapturedFrameData の配列)

StopCapturingFrames(); // キャプチャ停止

このように、FrameGrabberは本来C++のAPIです。レベルシーケンスの動画書き出し(Movie Render)など、エンジン内部のキャプチャ処理でも利用されています。ブループリント側に「FrameGrabber」という名前のノードが標準で見当たらないのはこのためで、BPから使うには後述のとおり何らかの橋渡しが必要になります。

ブループリントから画面を取得する現実的な手段

「ブループリントから画面フレームを取得したい」という目的に対しては、FrameGrabberに固執するよりも、次の3つの選択肢から用途に合うものを選ぶのが実用的です。

  • Scene Capture 2D+Render Target: カメラ視点をRender Target(UTextureRenderTarget2D)へ描画し、その内容をテクスチャやファイルとして取り出す。BPノードだけで完結しやすい。
  • ハイレゾスクリーンショット系コンソールコマンド: HighResShot などをExecute Console Commandで実行し、実際に表示されている最終画面をPNGとして保存する。最も手軽。
  • FrameGrabberをC++でラップしてBPへ公開: FFrameGrabberを使うアクターやサブシステムをC++で実装し、開始・取得・停止をUFUNCTION(BlueprintCallable)でノード化する。低レイテンシ・連続フレーム取得が必要な場合向け。

各手段の比較

それぞれ、得意な用途・実装コスト・取得できる対象が異なります。下表を目安に選んでください。

手段 取得対象 BPだけで可能か 主な用途 実装コスト
Scene Capture 2D+Render Target 指定カメラ視点のシーン(最終UIは含まない) 可能 ミニマップ・鏡・監視カメラ・サムネイル 低〜中
ハイレゾスクリーンショット(HighResShot 実際に表示されている最終画面 可能(コマンド実行のみ) スクリーンショット保存
FrameGrabber(C++でラップ) ビューポートの描画フレーム(連続取得) 不可(C++が必要) 動画化・外部転送・毎フレーム処理

ポイントは「最終的に画面に出ているUI込みの絵」が欲しいのか、「3Dシーンの絵」が欲しいのかです。HUDやUMG(ウィジェット)まで含めたい場合はスクリーンショット系が確実で、Scene Capture 2Dは原則として3Dシーンの描画が対象になります。

Scene Capture 2Dでの画面取得手順

ブループリント中心で進めるなら、まずはScene Capture 2Dを使う方法が扱いやすいです。考え方は「カメラ(Scene Capture 2D)が映した映像をRender Targetという受け皿に描き込み、それを参照する」というものです。

大まかな流れは次のとおりです。

  • コンテンツブラウザでRender Target(Texture Render Target 2Dアセットを作成し、解像度(例: 1920×1080)を設定する。
  • レベルにScene Capture 2Dアクターを配置するか、アクターのコンポーネントとしてScene Capture Component 2Dを追加する。
  • そのコンポーネントのTexture Targetに、作成したRender Targetを割り当てる。
  • キャプチャしたい視点にScene Capture 2Dを向ける(プレイヤーカメラと同じ位置・回転に追従させると、画面に近い絵が得られる)。
  • Render Targetの内容を、マテリアルで表示する/テクスチャ化する/ファイルへ書き出す、のいずれかで利用する。

取得した絵をテクスチャとして再利用したい場合、ブループリントのDraw Material to Render TargetなどでRender Targetへ描画したうえで、コンテンツブラウザ上でRender Targetを右クリックし「Create Static Texture」から静的テクスチャ化する、という手順が使えます。ランタイムでファイル保存やピクセル配列としての読み出しまで行いたい場合は、Render TargetのピクセルをFColor配列として読み出す処理が必要になり、ここはC++や追加のプラグインに頼ることが多くなります。

キャプチャのタイミング制御は従来どおりブループリントのイベントで行えます。たとえば、特定の入力やゲーム内イベントを起点にCapture Scene系の更新を呼ぶ、といった構成です。なお、Scene Capture 2Dは常時キャプチャ(毎フレーム更新)にしておくと負荷が高くなるため、必要なタイミングだけ更新する設定にして、撮りたい瞬間にブループリントから明示的にキャプチャを走らせると、パフォーマンスを抑えつつ目的の絵を得やすくなります。

FrameGrabberをC++でBPに公開する場合の考え方

どうしてもFrameGrabberそのものをブループリントから扱いたい、あるいは毎フレームの描画結果を低レイテンシで受け取りたい場合は、C++で薄いラッパーを用意します。基本方針は「FFrameGrabberの生成・開始・取得・停止をC++側に閉じ込め、ブループリントには操作の入り口だけを公開する」というものです。

  • キャプチャ管理用のアクター、またはサブシステムをC++で作成する。
  • その内部でFFrameGrabberを生成し、StartCapturingFramesで開始、必要なフレームでCaptureThisFrame、結果をGetCapturedFramesで受け取る。
  • 「開始」「1枚取得」「停止」などの操作をUFUNCTION(BlueprintCallable)として公開し、ブループリントからノードとして呼べるようにする。
  • 取得したフレームデータ(ピクセル)は、テクスチャ化したり、外部送信や保存処理へ渡したりする。

この構成にしておくと、タイミングや条件分岐といったゲームロジック側はブループリントで組みつつ、重い描画取得処理はC++に任せられます。ビルド設定では、MovieSceneCaptureモジュールへの依存をBuild.csに追加する必要がある点に注意してください。実装コストは高めなので、要件が単発のスクリーンショットやサムネイル生成にとどまるなら、前述のScene Capture 2Dやコンソールコマンドで済ませるほうが手間に見合います。

// 最終画面をそのまま保存したいだけなら、コンソールコマンドが手軽

// Blueprint: Execute Console Command ノード

Command: "HighResShot 1920x1080"

上記のHighResShotは、実際に表示されている最終画面(UIを含む構成も可能)を高解像度でキャプチャし、プロジェクトのSaved/Screenshots以下へ保存します。FrameGrabberのように描画結果をプログラム内で連続的に扱う用途には向きませんが、「ボタンを押したらスクリーンショットを残す」程度であればこれで十分です。

落とし穴・注意点

注意点 内容
FrameGrabberにBP標準ノードは無い FFrameGrabberはC++のクラスで、そのままではブループリントから呼び出せません。BPで使うにはC++ラッパーが必須です。
C++実装が必要になる場面が多い 連続フレーム取得・動画化・外部への映像転送など本格的な用途では、C++(MovieSceneCaptureモジュールの参照や独自プラグイン)が前提になります。
パフォーマンスとメモリ 毎フレームのキャプチャやピクセル読み出しはGPU→CPU転送を伴い、コストが高くなりがちです。解像度・頻度を抑え、高解像度を常時取得し続けない設計が無難です。
取得対象の違い Scene Capture 2Dは原則として3Dシーンが対象で、HUDやUMGのUIは含まれないことがあります。UI込みの最終画面が欲しい場合はスクリーンショット系を使います。
バージョン差・API変更 キャプチャ周りのAPIやノードはエンジンのバージョンで挙動・名称が変わることがあります。利用中のUE5バージョンのドキュメントで最新の仕様を確認してください。

よくある質問(FAQ)

Q. ブループリントだけでFrameGrabberを使えますか?
A. FrameGrabber(FFrameGrabber)はC++のクラスで、ブループリントの標準ノードとしては提供されていません。BPだけで完結させたい場合は、Scene Capture 2D+Render Target、またはハイレゾスクリーンショット用のコンソールコマンドを使うのが現実的です。FrameGrabber本体を使いたいなら、C++で実装してBPへノード公開する必要があります。

Q. UI(HUDやUMG)を含めた画面を保存したいときは?
A. 実際に表示されている最終画面を取りたい場合は、HighResShotなどのスクリーンショット系コマンドが確実です。Scene Capture 2Dは基本的に3Dシーンの描画が対象で、UIが含まれないことがあります。

Q. リアルタイムで毎フレーム画面データを処理したい場合はどうすればよいですか?
A. 低レイテンシで連続的にフレームを取り出す必要があるなら、FrameGrabberをC++で利用するのが向いています。StartCapturingFramesCaptureThisFrameGetCapturedFramesといった処理をアクターやサブシステムにまとめ、開始・取得・停止をBlueprintCallableなノードとして公開すれば、タイミング制御はブループリント側から行えます。ただし実装・パフォーマンス調整の負担は大きくなるため、用途が「スクリーンショット」程度であれば前述の代替手段で十分です。

まとめ

FrameGrabberはレンダリング結果を効率よく取得するためのC++のAPIであり、ブループリントから直接呼べる標準ノードはありません。したがって、ブループリント中心で画面を取得したい場合は、まずScene Capture 2D+Render Targetやハイレゾスクリーンショットのコンソールコマンドといった代替手段を検討し、連続フレーム取得や動画化など本格的な用途で必要になったときに、FrameGrabberをC++でラップしてBPへ公開する、という順序で考えると無理がありません。目的(最終画面か3Dシーンか、単発か連続か)を整理したうえで、最小のコストで要件を満たす手段を選びましょう。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ブループリントで途中から親クラスを指定する方法
  2. C++で編集となっているコンポーネントをブループリントで編集する方法
  3. Boolean変数の初期値を変更する方法
  4. ブループリントで特定のキーが押された時にイベントを発火させる方法
  5. ブループリントで配列からインデックスを指定して取得する方法
  6. Blueprintで「Esc」キーを使ってイベントを発生させる方法
  7. Blueprintで「Cast To」を使い、複数のクラスに対応する方法
  8. Blueprintで指定した確率で処理を分岐させる方法
  9. FrameGrabberをBlueprintで使用する方法
  10. ブループリントで現在日時を取得する方法

最近更新/作成されたページ