はじめに
ゲーム開発では、ゲーム世界と画面に固定されたUI要素(HUDやメニュー)を同時に表示する必要があります。ゲーム世界のカメラが動いたとき、背景や敵はスクロールしますが、スコア表示やボタンは動くべきではありません。こうした「レイヤー分け」を実現するのがCanvasLayerノードです。
CanvasLayerを使えば、複数の描画レイヤーを重ね合わせ、それぞれに異なるカメラ追従設定を適用できます。この記事では、CanvasLayerの基本的な使い方、プロパティ、そして実践的な活用法を詳しく解説します。
CanvasLayerとは?
CanvasLayerは、2D画面を複数のレイヤーに分割して管理するノードです。CanvasLayerの子に配置されたノードは、ゲーム世界のカメラに追従せず、ビューポート(画面)に相対的に描画されます。つまり、HUDやポーズメニュー、フェードアウト用の半透明レイヤーなど、「常に画面の同じ位置に表示したい要素」を管理するのに最適です。
映画のスクリーンに直接ステッカーを貼り付けたイメージです。スクリーンの映像(ゲーム世界)がどう動こうと、ステッカー(CanvasLayerの子)はスクリーンの同じ位置に留まります。
継承ツリー:
CanvasLayer → Node
Node直下を継承しており、シーンツリーのどこにでも配置できます。通常、CanvasLayerの子にはUI要素(Label、Button、ColorRect等)を配置します。

このノードを使うべき場面
- HUD・スコア表示:プレイヤーの体力ゲージ、スコア、アイテム情報。画面上部に常に表示
- ポーズメニュー・オプション画面:ゲーム一時停止時に表示するUIパネル。ゲーム世界の背後に暗くなったオーバーレイを配置
- フェードイン・フェードアウト:黒い画面が徐々に透明になるエフェクト。全画面を覆うColorRectをCanvasLayerに配置
- ミニマップの固定表示:画面の一角に配置されたミニマップ。ゲーム世界のカメラが動いても動かない
別のノードが適切な場面:
- ゲーム世界の敵やアイテムなど、カメラと同期して動く要素は通常のNode2D。
- 複雑なUIパネルはCanvasLayerよりも、専用のControl(UI)ノードを使う方がシンプル。
- 複数の独立したゲーム画面(例:分割画面マルチプレイ)を実装する場合はSubViewportを検討。
主なプロパティと機能
| プロパティ・メソッド | 型 | 役割 |
|---|---|---|
layer |
int | 描画順序(デフォルト:1)。数値が大きいほど前面に描画。複数CanvasLayerがある場合に重要 |
offset |
Vector2 | CanvasLayer全体を画面上でオフセット。(0, 0)がデフォルト |
follow_viewport_enabled |
bool | trueにするとCanvasLayerがビューポートの拡大縮小に追従(デフォルト:false) |
follow_viewport_scale |
float | ビューポートスケールの倍率。follow_viewport_enabledがtrueのときに機能 |
canvas_transform |
Transform2D | このCanvasLayerの描画変換を取得・設定(高度な使用法) |
GDScript コード例1:スコア表示HUDを実装
extends Node
# CanvasLayerの子に配置されたLabel
@onready var score_label = $CanvasLayer/ScoreLabel
@onready var health_label = $CanvasLayer/HealthLabel
var current_score = 0
var player_health = 100
func _process(delta):
# ゲーム内の値が変わるたびにUIを更新
# (プレイヤースクリプトからシグナルを受け取るのが一般的)
score_label.text = "Score: " + str(current_score)
health_label.text = "Health: " + str(player_health)
func add_score(points):
current_score += points
score_label.text = "Score: " + str(current_score)
GDScript コード例2:フェードイン・アウトエフェクト
extends Node
@onready var fade_rect = $CanvasLayer/FadeRect # ColorRectノード
func _ready():
# 初期状態は完全に透明
fade_rect.color = Color(0, 0, 0, 0)
func fade_in(duration = 1.0):
"""画面をフェードイン(黒から透明へ)"""
var tween = create_tween()
tween.tween_property(fade_rect, "color", Color(0, 0, 0, 0), duration)
func fade_out(duration = 1.0):
"""画面をフェードアウト(透明から黒へ)"""
var tween = create_tween()
tween.tween_property(fade_rect, "color", Color(0, 0, 0, 1), duration)
func _process(delta):
# キー入力でテスト
if Input.is_action_just_pressed("ui_accept"):
fade_out(2.0)
if Input.is_action_just_pressed("ui_cancel"):
fade_in(2.0)

もっと使いこなす:カスタマイズできるパラメータ
| パラメータ・テクニック | 変えると何が起きるか |
|---|---|
layer = 0(負数も可) |
ゲーム世界の背後に描画。背景エフェクトやスターフィールド用 |
layer = 10等、高い値 |
最前面に描画。システムメニューやダイアログボックスを重ねる |
offset = Vector2(100, 50) |
CanvasLayer全体を右100、下50ピクセルずらす。UI全体の位置調整に使用 |
follow_viewport_enabled = true |
ウィンドウのリサイズやズームに応じてUI要素も拡大縮小。解像度対応が簡単に |
| 複数CanvasLayerを組み合わせ | layer値でUIの重ね順を制御。HUD、メニュー、通知など、複数レイヤーを効率的に管理 |
まとめ
CanvasLayerは、ゲーム世界とUI要素を分離して管理するノードです。layerプロパティで描画順序を制御し、offsetで位置を調整することで、複雑なUI構成を効率的に実装できます。HUD、メニュー、フェードエフェクトなど、モダンなゲーム開発に欠かせないノードです。
- CanvasLayerの子はビューポット(画面)に相対的に描画される
- layerプロパティで描画順序を制御。数値が大きいほど前面
- follow_viewport_enabledで、ウィンドウリサイズに自動追従する設定も可能
次回は、ゲーム画面内に独立した「別の画面」を作り出すSubViewportについて詳しく解説します。ゲーム内のモニター、ミニマップ、鏡などの表現で活躍するノードです。
シリーズ:Godot 4 ノード解説
- 001〜035:各種基本ノード
- 036〜075:UI・入力ノード
- 076〜085:アニメーション・制御ノード
- 086:Path2D
- 087:PathFollow2D
- 088:NavigationAgent2D
- 089:CanvasLayer(この記事)
- 090:SubViewport
この記事はGodot 4.xをもとに執筆しています。


コメント