はじめに
「ゲーム画面の中にミニゲーム画面を映したい」「3Dキャラクターのプレビューをメニューに表示したい」——こういった「画面の中に別の画面を埋め込む」演出を実現するのが SubViewportContainer です。仕組みを知ると、ぐっと表現の幅が広がります。
この記事では、SubViewportContainer の構造・使いどころ・基本的なセットアップ手順を紹介します。
SubViewportContainerとは?
SubViewportContainer は 子ノードに置いた SubViewport の映像を、UIコントロールとして画面上に表示するコンテナです。SubViewport は独立したレンダリング空間(仮想カメラ)を持ち、そこに映っている映像をテクスチャとしてUIに貼り付けます。
監視カメラのモニターをイメージしてください。別の部屋(SubViewport)で起きていることをモニター画面(SubViewportContainer)に映す——その仕組みをゲーム内UIで再現できるのが SubViewportContainer です。
継承ツリーは SubViewportContainer → Container → Control → CanvasItem → Node です。必ず直下に SubViewport ノードを1つ子として持つことでセットとして機能します。SubViewport の中には、2D・3D を問わずノードを自由に配置できます。

このノードを使うべき場面
- キャラクタープレビュー:装備変更メニューで3Dキャラクターをぐるぐる回してプレビューするUI
- ミニマップ:メインカメラとは別のカメラでマップを俯瞰して、HUDの一角に表示する
- 監視カメラ映像:ゲーム内に設置したカメラの映像をモニターUIに流す演出
- 画面内画面(PinP):別ステージや別シーンの映像をメイン画面にオーバーレイする
- インベントリのアイテムプレビュー:選択したアイテムの3Dモデルをパネル内で回転表示する
別のノードが適切な場面:
- 静止画像を表示するだけなら →
TextureRectで十分。SubViewportContainer はリアルタイム描画が必要な場合に使う - ミニマップが2D限定で軽量に済むなら → カメラの
cull_maskとレイヤー分けで対応する方法も検討する
主なプロパティと機能
SubViewportContainer のプロパティと、セットで使う SubViewport のプロパティをまとめました。
| 対象 | プロパティ | 役割 |
|---|---|---|
| SubViewportContainer | stretch |
true にすると SubViewport の映像をコンテナサイズに合わせて引き伸ばす(通常は true にする) |
| SubViewportContainer | stretch_shrink |
レンダリング解像度を下げる係数。2 にすると描画は半分の解像度で行いUIサイズは維持(軽量化に使う) |
| SubViewport | size |
SubViewport の解像度(ピクセル)。ここを小さくするとパフォーマンスが向上する |
| SubViewport | render_target_update_mode |
描画更新のタイミング(DISABLED / ONCE / WHEN_VISIBLE / ALWAYS) |
| SubViewport | transparent_bg |
true にすると背景を透明にし、下のUIが透けて見える |
render_target_update_mode の選び方はパフォーマンスに直結します。
| モード | 動作 | 向いている場面 |
|---|---|---|
DISABLED |
描画しない | 非表示中のプレビューを停止して節約したいとき |
ONCE |
1フレームだけ描画 | 静的なプレビュー(回転しないアイテム表示など) |
WHEN_VISIBLE |
表示中のみ毎フレーム描画 | 表示・非表示が切り替わるプレビューUI(推奨) |
ALWAYS |
常に毎フレーム描画 | 常時表示のミニマップなど(負荷注意) |
@onready var sub_viewport: SubViewport = $SubViewportContainer/SubViewport
@onready var container: SubViewportContainer = $SubViewportContainer
func show_preview() -> void:
container.visible = true
# 表示中のみ描画してパフォーマンスを節約
sub_viewport.render_target_update_mode = SubViewport.UPDATE_WHEN_VISIBLE
func hide_preview() -> void:
container.visible = false
sub_viewport.render_target_update_mode = SubViewport.UPDATE_DISABLED
コード例:SubViewport 内のキャラクターをマウスドラッグで回転する
var dragging := false
var last_mouse_x := 0.0
@onready var character: Node3D = $SubViewportContainer/SubViewport/Character
func _input(event: InputEvent) -> void:
if event is InputEventMouseButton:
dragging = event.pressed
last_mouse_x = event.position.x
if event is InputEventMouseMotion and dragging:
var delta_x = event.position.x - last_mouse_x
character.rotate_y(deg_to_rad(-delta_x * 0.5))
last_mouse_x = event.position.x
もっと使いこなす:カスタマイズできるパラメータ
まずは基本を動かしてみてから、余裕が出たら試してみてください。
| パラメータ・テクニック | 変えると何が起きるか |
|---|---|
stretch_shrink を 2 に |
レンダリング解像度が半分になりGPU負荷が下がる。軽量化したいプレビューに有効 |
transparent_bg を true に |
SubViewport の背景が透明になり、背景色なしでキャラクターだけを浮かせて表示できる |
render_target_update_mode を WHEN_VISIBLE に |
非表示時に描画を止めて節約できる。複数のプレビューを持つUIで特に効果的 |
| AspectRatioContainer で包む | プレビュー枠の縦横比を固定したまま画面サイズに追従させられる。026 との組み合わせが鉄板 |
SubViewport の size を小さくする |
描画コストを下げられる。256×256 や 512×512 程度でもプレビュー用途なら十分なことが多い |

まとめ
SubViewportContainer は 「別の描画空間の映像をUIとして貼り付けるコンテナ」 です。
- 必ず直下に SubViewport を置き、その中にカメラと表示したいノードを配置するのが基本構成
render_target_update_modeをWHEN_VISIBLEにするとパフォーマンスを節約できるtransparent_bg+AspectRatioContainerの組み合わせでスタイリッシュなプレビューUIが作れる
次回は、画像テクスチャをUIに表示する基本ノード TextureRect を紹介します。
シリーズ:Godot 4 ノード解説
- 001:Node(基底クラス)
- 002:Node2D
- 003:Sprite2D
- 004:AnimatedSprite2D
- 005:CharacterBody2D
- 006:CollisionShape2D
- 007:Area2D
- 008:RigidBody2D
- 009:Camera2D
- 010:Label
- 011:RichTextLabel
- 012:LineEdit
- 013:Button
- 014:HBoxContainer
- 015:VBoxContainer
- 016:GridContainer
- 017:ScrollContainer
- 018:Panel
- 019:TabContainer
- 020:SplitContainer
- 021:HSplitContainer
- 022:VSplitContainer
- 023:FlowContainer
- 024:MarginContainer
- 025:CenterContainer
- 026:AspectRatioContainer
- 027:SubViewportContainer(この記事)
- 028:TextureRect
- 029:ColorRect
- 030:ProgressBar
この記事はGodot 4.xをもとに執筆しています。


コメント