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

はじめに

ゲームを開発していると、「カメラのズームに反応してほしくないUI」「常に画面の上に表示したいHUD」が必要になります。例えば、HPゲージやスコア表示、一時停止パネル—これらはプレイヤーキャラクターがどこにいても、画面のどこかに固定されるべきです。こうした「カメラに依存しない描画」を実現するのが CanvasLayer です。

この記事では、CanvasLayer の基本的な役割から、layer プロパティで描画順序を制御する方法、follow_viewport_enabled で視点を固定する仕組みまで、実践的に解説します。

CanvasLayerとは?

CanvasLayer は、カメラに依存しない独立した描画レイヤーを作るノードです。CanvasLayer 以下のノードは、カメラのズーム・パン・回転の影響を受けず、常に画面上の固定位置(またはビューポート基準)で描画されます。

例えるなら、映画撮影で複数のレンズを重ねる手法。背景レンズはズームするが、字幕テロップはいつも同じサイズで画面下部に固定—CanvasLayer がそれです。

継承ツリー:

CanvasLayer → Node → Object

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

使うべき場面

  • HUD(HP、スコア、タイマー):ゲーム画面の進行に関わらず常時表示
  • ミニマップ:画面コーナーに固定表示、ズームに影響されない
  • 一時停止パネル:メニューやポーズ画面、暗い半透明パネル
  • フェード暗幕:シーン遷移時の黒フェードイン・アウト
  • マウスカーソル UI:マウス座標を追従する UI 要素

使わない場面

  • プレイ画面の背景やメインキャラクター:通常の Node2D 構造で十分
  • カメラの動きに追従する UI:CanvasLayer は向かない(UI のパラレックス効果)

主なプロパティと機能

プロパティ 説明
layer int 描画順(大きい数値ほど前面に表示。-128〜127)
offset Vector2 レイヤー全体のオフセット(ピクセル単位)
follow_viewport_enabled bool true=カメラ追従、false=世界座標固定
follow_viewport_scale float follow_viewport_enabled=true のとき、スケール倍率
transform Transform2D レイヤーの変換行列(位置、回転、スケール)
visible bool レイヤー全体の表示/非表示

基本的な使用例1:HUD を CanvasLayer に配置


extends Control

# シーン構造:
# Root (Node2D) ← ゲーム世界
#   ├─ Player
#   ├─ Enemies
#   └─ HUDLayer (CanvasLayer) ← HUD は独立
#       ├─ HPLabel
#       ├─ ScoreLabel
#       └─ TimerLabel

@onready var hud_layer = $HUDLayer
@onready var hp_label = $HUDLayer/HPLabel

func _ready():
    # HUD レイヤーは常に前面(layer=1)
    hud_layer.layer = 1

    # カメラに追従しない(固定位置)
    hud_layer.follow_viewport_enabled = false

func update_hp(current_hp: int, max_hp: int):
    hp_label.text = "HP: %d / %d" % [current_hp, max_hp]

フェード暗幕例2:シーン遷移時のフェードイン・アウト


extends CanvasLayer

@onready var fade_rect = $ColorRect

func _ready():
    # フェードレイヤーを最前面に
    layer = 100
    fade_rect.color = Color.BLACK
    fade_rect.modulate.a = 0.0  # 最初は透明

func fade_in(duration: float):
    var tween = create_tween()
    tween.tween_property(fade_rect, "modulate:a", 1.0, duration)
    await tween.finished

func fade_out(duration: float):
    var tween = create_tween()
    tween.tween_property(fade_rect, "modulate:a", 0.0, duration)
    await tween.finished




CanvasLayerの層別描画順序
layer値が大きいほど画面の前面に描画されます

もっと使いこなす:layer と follow_viewport の組み合わせ

設定パターン 動作 用途
follow_viewport_enabled=false 世界座標固定、カメラズーム無視 HUD、UI(最も一般的)
follow_viewport_enabled=true
follow_viewport_scale=1.0
カメラの動きに追従、ズームと同じ倍率 パーティクル、背景エフェクト
follow_viewport_enabled=true
follow_viewport_scale=0.5
カメラ追従、ズームの半分(パラレックス効果) 背景レイアー(視差効果)
follow_viewport_enabled=true
follow_viewport_scale=0.0
カメラに追従しない(固定背景) 遠い背景、スターフィールド




follow_viewport_enabledの効果比較
follow_viewport_enabledとfollow_viewport_scaleでレイヤーの動きを制御できます

実践例:複数レイヤーの階層構造


extends Node2D

# シーン構造:
# Root
#   ├─ BackgroundLayer (CanvasLayer, layer=-10)
#   │   └─ StarField (視差背景)
#   ├─ GameWorld (通常の Node2D)
#   │   ├─ Player
#   │   └─ Enemies
#   ├─ EffectLayer (CanvasLayer, layer=0)
#   │   └─ Explosions (パーティクル)
#   └─ HUDLayer (CanvasLayer, layer=100)
#       ├─ HPBar
#       ├─ ScoreLabel
#       └─ PauseMenu

@onready var background_layer = $BackgroundLayer
@onready var effect_layer = $EffectLayer
@onready var hud_layer = $HUDLayer

func _ready():
    # 背景レイヤー:遠い背景として視差効果
    background_layer.layer = -10
    background_layer.follow_viewport_enabled = true
    background_layer.follow_viewport_scale = 0.3  # カメラズームの30%だけ動く

    # エフェクトレイヤー:ゲーム世界と同じズーム
    effect_layer.layer = 0
    effect_layer.follow_viewport_enabled = true
    effect_layer.follow_viewport_scale = 1.0

    # HUD レイヤー:UI は常に固定
    hud_layer.layer = 100
    hud_layer.follow_viewport_enabled = false

func trigger_effect(pos: Vector2):
    # エフェクトレイヤーに爆発を生成
    var explosion = preload("res://scenes/explosion.tscn").instantiate()
    explosion.global_position = pos
    effect_layer.add_child(explosion)

CanvasLayer と Control(UI)の違い

項目 CanvasLayer Control(UI)
描画方式 2D ワールド座標 相対レイアウト(親に基づく)
カメラ影響 設定で制御可能 常に UI 画面空間
スケーリング 手動で設定 自動(アンカー・マージン)
推奨用途 HUD、エフェクト、背景 メニュー、UI パネル

まとめ

CanvasLayer は、ゲームの描画を層別に管理する強力なノードです。layer で描画順序を制御し、follow_viewport_enabled で視点固定/カメラ追従を切り替えれば、HUD からエフェクト、背景まで、多彩なゲーム表現が実現できます。

  • 層別描画管理:layer プロパティで複数レイヤーの描画順序を明確に制御
  • カメラ独立性:follow_viewport_enabled=false で HUD をカメラの動きから保護
  • 視差効果:follow_viewport_scale で遠い背景と近い背景の速度差を演出

次のステップ:これで 2D ノード解説は一区切り。次回からは 3D ノード編(Node3D、MeshInstance3D など)へ進みます。立体的なゲーム表現の世界へようこそ!

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

  • 001: Node2D
  • 002: Sprite2D
  • 003: CollisionShape2D
  • 004: CharacterBody2D
  • 005: RigidBody2D
  • 006: Area2D
  • 007: Control
  • 008: Button
  • 009: Label
  • 010: TextEdit
  • 011: ItemList
  • 012: TabContainer
  • 013: Timer
  • 014: Tween
  • 015: Camera2D
  • 016: ParallexBackground
  • 017: TileMap(旧)
  • 018: Path2D
  • 019: PathFollow2D
  • 020: RemoteTransform2D
  • 021: Marker2D
  • 022: Node
  • 023: Resource
  • 024: Script
  • 025: Signal
  • 026: Input
  • 027: Physics2DServer
  • 028: VisibleOnScreenNotifier2D
  • 029: RayCast2D
  • 030: ShapeCast2D
  • 031: PinJoint2D
  • 032: DistanceJoint2D
  • 033: HingeJoint2D
  • 034: SliderJoint2D
  • 035: ConeTwistJoint2D
  • 036: Generic6DOFJoint2D
  • 037: Polygon2D
  • 038: ColorRect
  • 039: NinePatchRect
  • 040: TextureRect
  • 041: StaticBody2D
  • 042: TileMapLayer
  • 043: AnimationPlayer
  • 044: AnimationTree
  • 045: AudioStreamPlayer
  • 046: AudioStreamPlayer2D
  • 047: GPUParticles2D
  • 048: CPUParticles2D
  • 049: Line2D
  • 050: CanvasLayer

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

コメント