イントロダクション:なぜSubViewportが重要なのか
Godot Engineでゲームを制作する際、単一の画面で全てを表現するだけでは、表現の幅に限界があります。例えば、画面の隅に ミニマップ を表示したい、2Dゲームの中に立体的な 3Dモデルのウィンドウ を埋め込みたい、あるいは動的なテクスチャとして画面 の一部を再利用したい、といった高度な視覚効果を実現するにはどうすれば良いでしょうか。
その鍵を握るのが、Godotの強力なノードであるSubViewportです。
SubViewportは、メインのビューポートとは独立した「仮想的な画面」を作成するためのノードです。この仮想画面は、独自のシーンツリー、カメラ、レンダリング設定を持つことができ、その結果をテクスチャとして取得し、メイン画面のどこにでも表示できます。これにより、Godotの表現力と柔軟性は飛躍的に向上します。
本記事では、初心者から中級者の方を対象に、SubViewportの基本的な概念から、ゲーム制作で即座に役立つ3つの主要な活用法(ミニマップ、3D in 2D、レンダーテクスチャ)について、具体的なコード例を交えて徹底的に解説します。
SubViewportの基本概念とViewportTexture
SubViewportノードは、それ自体が独立したレンダリングパイプラインを持つコンテナです。このノードの子として配置されたシーンは、メイン画面とは切り離されてレンダリングされます。
この独立したレンダリング結果を取得するために使用するのが、ViewportTextureです。SubViewportのプロパティにあるRenderTargetを有効にすると、そのビューポートの出力がテクスチャとして利用可能になります。このテクスチャをTextureRectやSprite2D、あるいは3Dマテリアルに適用することで、メ インシーンに組み込むことができます。
SubViewportの基本的な設定
| プロパティ | 設定値 | 目的 |
|---|---|---|
| Size | 任意の解像度 | ビューポートのレンダリングサイズを決定します。 |
| Usage | RenderTarget | このビューポートをテクスチャとして使用することを有効にします。 |
| Update Mode | Always / WhenVisible | レンダリングを更新するタイミングを設定します。ミニマップなど常に最新の情報が必要な場合はAlwaysを選択します。 |
活用法1: 実用的なミニマップの実装
ミニマップは、SubViewportの最も一般的で実用的な応用例の一つです。
実装手順
- シーンの準備: メインのゲームシーン(例:
World)にSubViewportノードを追加します。 - カメラの配置:
SubViewportの子として、ミニマップ専用のCamera2D(2Dゲームの場合)またはCamera3D(3Dゲームの場合)を配置します。 - カメラの設定: ミニマップカメラは、メインカメラとは独立して、プレイヤーや特定のエリアを上空から見下ろすように設定します。
- 表示:
SubViewportの兄弟ノードとしてTextureRectを追加し、そのTextureプロパティに「新規ViewportTexture」を設定し、ドロップダウンから作成したSubViewportを選択します。
GDScriptによるカメラ追従の例
ミニマップカメラをプレイヤーに追従させるためのシンプルなGDScriptです。
# minimap_camera.gd (SubViewport内のCamera2Dにアタッチ)
extends Camera2D
@export var target_node_path: NodePath
var target: Node2D
func _ready():
# エディタで設定されたパスからターゲットノードを取得
target = get_node_or_null(target_node_path)
if target == null:
print("Error: Target node not found for minimap camera.")
set_process(false) # 処理を停止
func _process(delta):
if target:
# ターゲットの位置にカメラを移動させる
global_position = target.global_position
# 必要に応じてズームレベルを調整
zoom = Vector2(0.5, 0.5)
活用法2: 2Dゲームに3D要素を組み込む (3D in 2D)
Godotは2Dと3Dのハイブリッド開発に優れていますが、SubViewportを使うことで、2DのUI要素として3Dシーンをシームレスに組み込むことができます。
実装手順
- SubViewportの設定: 2DシーンのUIレイヤーに
SubViewportノードを配置し、RenderTargetを有効にします。 - 3Dシーンの構築:
SubViewportの子としてNode3D、Camera3D、そして表示したいMeshInstance3D(例: プレイヤーの3Dモデル、回転するアイテム)を追加します。 - カメラとライト:
Camera3Dは3D要素を適切に捉えるように配置し 、DirectionalLight3Dなどの光源も忘れずに配置します。 - 表示:
TextureRectにViewportTextureを設定し、2D画面に3Dシーンのレンダリング結果を表示します。
この手法は、インベントリ画面でプレイヤーの装備を3Dで表示したり、2Dパズルゲームのヒントとして3Dモデルを回転させたりするのに非常に有効です。
活用法3: レンダーテクスチャとしての応用
SubViewportの出力をテクスチャとして利用する機能は、単なるUI表示を超えた、より高度なグラフィック効果にも応用できます。これが レンダーテクスチャ としての活用です。
ユースケース:動的なポータルやセキュリティカメラ
ポータルや鏡、セキュリティカメラの画面などは、別の場所や視点をリアルタイムでレンダリングし、それをテクスチャとしてオブジェクトに貼り付けることで実現されます。
-
ポータル/鏡の作成:
- ポータル先の視点を担当する
SubViewportを作成します。 - その
SubViewport内に、ポータル先のシーンを映すCamera3Dを配置します。 - ポータルとなる3Dオブジェクト(例:
MeshInstance3D)のマテリアルに、ViewportTextureを適用します。
- ポータル先の視点を担当する
-
Shaderとの連携:
ViewportTextureは、シェーダーの入力テクスチャとして使用できます。例えば、セキュリティカメラの映像にノイズや歪みといったポストプロセス効果をシェーダーで適用し、よりリアルな表現を行うことができます。
# 3Dオブジェクトのマテリアルに動的にテクスチャを設定する例
extends MeshInstance3D
@export var target_viewport: SubViewport
func _ready():
# ViewportTextureを生成し、SubViewportの出力を設定
var viewport_texture = ViewportTexture.new()
viewport_texture.set_viewport_path(target_viewport.get_path())
# マテリアルを取得し、テクスチャを設定
var material = get_surface_override_material(0)
if material is StandardMaterial3D:
material.albedo_texture = viewport_texture
elif material is ShaderMaterial:
# シェーダーのuniformにテクスチャを設定
material.set_shader_parameter("screen_texture", viewport_texture)
まとめ
SubViewportノードは、Godot Engineにおける高度なレンダリング技術の基盤です。
| 活用法 | 目的 | 主な構成要素 |
|---|---|---|
| ミニマップ | 画面の隅にゲーム世界の俯瞰図を表示する。 | SubViewport + Camera2D/3D + TextureRect |
| 3D in 2D | 2DゲームのUI内に3Dモデルやシーンを埋め込む。 | SubViewport + Node3D + Camera3D |
| レンダーテクスチャ | 別の視点やシーンをリアルタイムでテクスチャとして再利用する。 | SubViewport + ViewportTexture + MeshInstance3D (マテリアル) |
これらのテクニックを習得することで、あなたのゲームはより洗練され、プレイヤーにリッチな体験を提供できるようになります。ぜひ、ご自身のプロジェクトでSubViewportを活用し、Godotの持つ無限の可能性を探求してみてください。