2026-06-14
UE5 でマルチカメラモニタリングシステムを作る

こんにちは!haruki です。今回は UE5 で「バーチャルライブ配信向けマルチカメラモニタリングシステム」を作ってみたので、その実装ポイントを解説します。
ビデオスイッチャーのように、レベル内に置いた複数のシネマティクカメラの映像を別ウィンドウで同時にプレビューして、クリックで Preview / Program を切り替える、というものです。
UE5のエディタを立ち上げず実行ファイルなどでも使えるようにしたかったため、EUWではなく、UMGで作成しています。 UMG だけだと別ウィンドウを作る機能は用意されていないので、Slate を直接触る必要があります。
UIはまだ微妙ですが、機能的には出来ていると思うので良ければ参考にしてください。
やりたかったこと・要件
- レベル内に複数のシネマティクカメラを配置
- すべてのカメラ映像を独立したウィンドウで同時にプレビュー
- クリックで Preview(次に出す予定)と Program(本番出力)を切り替え
- 何番のカメラが選択されてるかわかるようにする
- カメラの台数が増減してもコード変更なしでセットアップできるようにする
前提条件
- Unreal Engine 5.5
システム全体像
機能は大きく3つに分解できます。
- カメラを切り替える機能 — ボタンでPreview画面の切り替え / Preview→Program のスイッチングロジック
- カメラを RenderTarget で焼きだす機能 — CineCameraActorの映像をテクスチャとして取り出す
- 直感的に切り替える UI — 別ウィンドウでサムネを並べ、クリック操作で切り替える
データの流れはこんな感じです。
flowchart LR
Scene["UEシーン<br/>"] --> Cam1["BP_CineCameraActor #1"]
Scene --> Cam2["BP_CineCameraActor #2"]
Cam1 -- SceneCapture --> RT1["RT_Camera_01"]
Cam2 -- SceneCapture --> RT2["RT_Camera_02"]
Cam1 -. FOV 同期 .-> RT1
Cam2 -. FOV 同期 .-> RT2
RT1 --> MI["MI_RenderTarget_01<br/>(M_RenderTarget)"]
RT2 --> MI
MI --> ViewW["WBP_CameraView (Image)"]
ViewW --> Main["WBP_CameraMonitor_Main"]
Main --> SWin["SWindow<br/>(セカンドウィンドウ)"]各カメラが毎フレーム自分専用の RenderTarget に描画して、それをマテリアル経由で UMG の Image に表示、UMG 全体を Slate ウィンドウに載せて別ウィンドウで開く、という構成です。
以下、3つの機能ごとに実装を解説していきます。
機能①: カメラを RenderTarget で焼きだす

CineCameraActorの映像をテクスチャとして取り出す部分から作っていきます。
ここを実装するアセットが BP_CineCameraActor です。親クラスは CineCameraActor(UE 標準のシネマティクカメラ)で、そこに SceneCaptureComponent2D を追加しています。
追加した変数はシンプルです。
CameraID(int) — カメラ識別子RenderTargetTexture(TextureRenderTarget2D) — 出力先の RT
やっていることは、シネカメラの絵作り(焦点距離・センサーサイズ・被写界深度)を保ちつつ、その視点をそのまま RT に複製すること。普通の CameraActor ではなくシネカメラを採用しているのは、トラッキングフォーカスなど映像制作で使いたい機能がデフォルトで揃っているからです。
FOV の同期
ここでは CineCamera と SceneCapture の FOV を連動させる仕組みを実装します(画像右)。
SceneCapture と CineCamera は別物なので、CineCamera 側で焦点距離やセンサーサイズを変更しても、SceneCapture の絵作りは追従してくれません。これを放置するとモニタープレビューと本番カメラの絵がずれて、配信用途では致命的です。
解決策は単純で、毎 Tick で CineCamera の現在の FOV を取得して SceneCapture に流し込むだけです。
これだけで、シネカメラのレンズ設定変更が SceneCapture 側にも自動追従するようになります。
データ駆動でカメラを管理する

カメラの追加・削除を楽にするために、設定情報は DataTable に寄せています。
ST_CameraConfig(Struct)CameraName(FString)RenderTarget(TextureRenderTarget2D)
DT_CameraConfig(DataTable)- RowStruct:
ST_CameraConfig - Row:
RT_Camera_01〜RT_Camera_06を登録
- RowStruct:
こうしておくと、
- カメラの追加・削除が DataTable 編集だけで済む
- 名前と RT の参照を一元化できる
- Blueprint からのハードコードを排除できる
というメリットがあります。マテリアルは M_RenderTarget(ベース)+ MI_RenderTarget_01(インスタンス)を Image ウィジェットに割り当てて RT を表示しています。
機能②: カメラを切り替える

次に、Preview / Program を切り替えるスイッチングロジックを実装します。
スイッチャーは「今、本番に出ているカメラ(Program)」と「次に出す予定のカメラ(Preview)」の2系統を持つのが基本です。テレビ局のスイッチャーと同じ考え方で、いきなり Program に切り替えると放送事故のリスクがあるため、一度 Preview にセットしてから Take 操作で Program に反映する、という流れを採っています。

切替フロー
- グリッドの中からカメラサムネをクリック → Preview に乗る(ゲーム画面はまだ切り替わらない)
- Take ボタンを押すと Program に反映され、ゲーム画面のカメラが切り替わる
- 直前まで Program だったカメラは次の Preview 候補へ
クリック即切替は配信現場ではやらないので、ここはハード要件として最初から組み込んでいます。
内部で持っている状態
UI 側(WBP_CameraMonitor_Main)で次の状態を管理しています。
PreviewCamera— 現在 Preview にセットされている CameraIDProgramCamera— 現在 Program に出ている CameraIDOnCameraClicked— 個別カメラビューのクリックハンドラ
クリックされた CameraID を PreviewCamera に書き込んで色を更新、Take ボタンが押されたら ProgramCamera に転送して、ゲームのアクティブカメラを切り替える、という流れです。
機能③: 直感的に切り替える UI
最後に、ここまでの機能をオペレータが触るための UI 部分です。今回の実装で一番ボリュームがあるところでもあります。
UI は次の2段構成になっています。
WBP_CameraMonitor_Main— カメラビューをグリッド表示するルートウィジェットBP_SecondWindowActor— Slate で独立した第2ウィンドウを開いて、上記の UMG を載せる
ゲームのメインビューと同じウィンドウに UI を出してしまうと配信本番の映像とぶつかってしまうので、完全に独立した OS ウィンドウとして表示しています。
メイン UI: WBP_CameraMonitor

第2ウィンドウのルートウィジェットです。複数の WBP_CameraView をグリッド表示します。
主な変数とイベントはこんな感じです。
CameraContainer—WBP_CameraViewを並べるコンテナCameraMap(Map<int, WBP_CameraView>) — CameraID から個別ビューを引くテーブルInitCamera(CameraID)— 起動時にカメラ一覧を構築
初期化フロー
ポイントは GetAllWidgetsOfClass(WBP_CameraView) で配置済みのカメラビューを動的に集めてくるところです。各 WBP_CameraView に対して InitCamera(CameraID) を呼んで関連付けすれば、カメラ台数の増減にコード変更なしで追従できます。
個別カメラビュー WBP_CameraView

IMG_CameraFeed— RT をマテリアルMI_RenderTarget_01経由で表示TXT_CameraName—DT_CameraConfigから表示名を取得CameraViewButtonColor— 選択状態を色でフィードバック- クリック →
OnCameraClicked発火 → スイッチャー側で Preview / Program を更新
「いま何番のカメラが Preview / Program なのか」を色枠で示すことで、オペレータが目で見て即判断できるようにしています。
BP_SecondWindowActor
C++ で作成したクラスを継承した Blueprint です。MonitorWidgetClass に WBP_CameraMonitor_Main を設定して、レベルに1つ置くだけで第2ウィンドウが立ち上がります。
ライフサイクル
BeginPlay→ 自動オープンEndPlay→CloseWindow()で確実に後片付け(PIE 終了時にウィンドウが残らない)- ウィンドウ側の × クリック →
HandleWindowClosedでSpawnedWindowを Reset
まとめ
マルチカメラモニタリングシステムは、機能で分解すると「RenderTarget への焼き出し」「Preview / Program のスイッチング」「第2ウィンドウ上の UI」の3つに分けて整理できます。どれも UE 標準機能の組み合わせで実現できるので、慣れてしまえばそこまで複雑ではないかなと思います。
「UMG を別ウィンドウに出す」機能をプラグイン化しておくと色々な場面で使い回せるようにしておくと便利です。また、レンダーターゲットは描画負荷が高いので、それを下げる方法なども残していく予定です。
同じようなマルチカメラビュー機能を作りたい方の参考になれば幸いです。
最後まで読んでいただきありがとうございました。次回もぜひお楽しみに。