Godot入門:SubViewportの使い方と活用法

はじめに

ゲーム開発では、「ゲーム画面の中にもう一つ別の画面を作りたい」という場面があります。ゲーム内のテレビやモニター画面、ミニマップ、キャラクター選択画面のプレビュー、あるいは鏡にゲーム世界が映り込む表現——これらは「ビューポートの中にビューポート」を作る仕組みです。そうした複雑な描画を実現するのがSubViewportノードです。

SubViewportを使えば、独立した別のカメラで別のシーンを描画し、その結果をテクスチャとしてゲーム世界に埋め込むことができます。この記事では、SubViewportの基本的な使い方、セットアップ、そして実践的な活用法を詳しく解説します。

SubViewportとは?

SubViewportは、メインゲーム画面とは独立した描画領域を作るノードです。内部に独自のカメラを持ち、独立したシーンを描画した結果を「テクスチャ」として出力できます。これをSubViewportContainerに配置したり、ViewportTextureを使ってゲーム世界のオブジェクトに貼り付けたりすることで、ゲーム内の「画面」を実現します。

ゲーム画面の中に、もう一つ別のテレビやモニターが映っているイメージです。その「テレビ画面」の中では、メインゲーム画面とは別の映像が映っており、独自のカメラで制御されています。

継承ツリー:


SubViewport → Viewport → Node

Viewportを継承しており、独立した描画コンテキストを持ちます。通常、SubViewportをシーンツリーに配置し、その内部に2Dシーン(Camera2DやSprite2Dなど)を構築します。




SubViewportの概念図
SubViewportはメインゲーム画面とは独立した描画領域を作成。独自のカメラで別シーンを映し出す

このノードを使うべき場面

  • ゲーム内のモニター・テレビ画面:セキュリティカメラの映像、テレビの放映内容。画面内に別のシーンを映す。
  • ミニマップ(俯瞰カメラ):メインカメラとは別の位置から全体を俯瞰。敵の位置も一目瞭然。
  • キャラクター選択画面のプレビュー:選んだキャラクターが3Dで回転しながら表示される場面。
  • リアルタイムポータル・鏡:鏡に別の場所が映り込む、ポータルの先が見える表現。

別のノードが適切な場面:

  • 単純なUI(スコア表示、ボタン)はCanvasLayerの方がシンプル。
  • 単一のカメラでゲーム全体を描画する場合はCamera2Dで十分。
  • 複雑な3D表現はSubViewportではなく、Engine全体のMultiplayerやネットワーク機能を検討。

主なプロパティと機能

プロパティ・メソッド 役割
size Vector2i サブビューポートの解像度。(1024, 768)など。テクスチャ出力サイズに直結
render_target_update_mode UpdateMode enum DISABLED/ONCE/WHEN_VISIBLE/ALWAYS。描画頻度を制御(パフォーマンス最適化に重要)
transparent_bg bool trueで背景透明。falseで背景色は使う。ミニマップ等では透明が便利
get_texture() → ViewportTexture ViewportTexture サブビューポートの描画結果をテクスチャとして取得
world_2d World2D サブビューポート内の2D物理世界。独立した物理シミュレーション

GDScript コード例1:ミニマップの実装


extends Node2D

# SubViewportとその中のCamera2D
@onready var minimap_viewport = $CanvasLayer/SubViewportContainer/SubViewport
@onready var minimap_camera = $CanvasLayer/SubViewportContainer/SubViewport/Camera2D

var player: Node2D

func _ready():
player = get_tree().get_first_node_in_group("player")

# ミニマップのカメラを初期化
if minimap_camera:
minimap_camera.zoom = 0.1 # 俯瞰用に縮小

func _process(delta):
# ミニマップのカメラをプレイヤーに追従させる
if player and minimap_camera:
minimap_camera.global_position = player.global_position

GDScript コード例2:ゲーム内モニター画面の実装


extends Node

# SubViewportをテクスチャとして取得し、Sprite2Dに貼り付け
@onready var monitor_viewport = $SubViewport
@onready var monitor_sprite = $Monitor/MonitorScreen # Sprite2Dノード

func _ready():
# サブビューポートの描画結果をテクスチャ化
var viewport_texture = monitor_viewport.get_texture()

# Sprite2Dに貼り付け
if monitor_sprite:
monitor_sprite.texture = viewport_texture

# 解像度を設定
monitor_viewport.size = Vector2i(512, 384)

func _process(delta):
# サブビューポート内のカメラを制御(例:セキュリティカメラのパン)
var sub_camera = monitor_viewport.get_camera_2d()
if sub_camera:
sub_camera.global_position = Vector2(
sin(Time.get_ticks_msec() * 0.001) * 100,
0
)




SubViewportの実装例
SubViewportをシーンツリーに配置し、内部にCamera2Dなどのノードを配置。その描画結果がテクスチャとして取得される

もっと使いこなす:カスタマイズできるパラメータ

パラメータ・テクニック 変えると何が起きるか
render_target_update_mode = DISABLED 描画を停止。フレームレートが向上するが、映像は更新されない。セキュリティカメラのフリーズなど
render_target_update_mode = ONCE 1フレームだけ描画。静的なプレビュー画像に最適。メモリ効率良好
render_target_update_mode = WHEN_VISIBLE SubViewportContainerが画面に見える時だけ描画。パフォーマンスと見た目のバランスが良い
render_target_update_mode = ALWAYS 毎フレーム描画(デフォルト)。最も正確だが負荷が大きい
transparent_bg = true 背景を透明にして、その下のUIが見える。複数SubViewportの重ね合わせが可能
size を小さく設定 低解像度で描画。パフォーマンス向上。ミニマップなどでは十分な品質

まとめ

SubViewportは、ゲーム画面内に独立した「別の画面」を作り出すノードです。ミニマップ、ゲーム内モニター、鏡などのエフェクトなど、モダンなゲーム開発に欠かせない表現を実現できます。render_target_update_modeを活用すればパフォーマンスを最適化し、複数のSubViewportを組み合わせることで、より複雑で美しいビジュアルが表現できます。

  • SubViewportは独立した描画領域で、独自のカメラを持つ
  • size で解像度、render_target_update_mode でパフォーマンスを制御
  • get_texture()で描画結果をテクスチャとして取得し、ゲーム世界に埋め込める

次回は、2D空間を効率的にタイル状に管理するTileMapについて詳しく解説します。ドット絵ゲームやマップベースのゲーム開発に不可欠なノードです。

シリーズ:Godot 4 ノード解説

この記事はGodot 4.xをもとに執筆しています。

コメント