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





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

はじめに

Godot 4の照明システムを活かすには、単に光を配置するだけでなく、「光を遮る物体」を配置することが重要です。それがLightOccluder2Dです。このノードを使うことで、DirectionalLight2DやPointLight2Dから投影された影を画面に映し出し、ゲームシーンに奥行きと立体感をもたらします。

特に2Dゲームで「画面に本当に物体が存在する感覚」を与えるために、LightOccluder2Dは欠かせません。

LightOccluder2Dとは?

LightOccluder2Dは「光の前に置いた板」のようなノードです。その形に合わせて光が遮られ、影が落ちます。DirectionalLight2DやPointLight2Dのshadow_enabledがtrueになっていることが条件です。

継承ツリー:

LightOccluder2D → Node2D → CanvasItem → Node

このノードは物理演算や衝突判定を持たず、純粋に「光を遮る形状」のみを定義します。形状はOccluderPolygon2Dリソースで定義され、複雑な多角形でも簡単に設定できます。




LightOccluder2Dの影の投影
LightOccluder2Dが光を遮ることで、その背後に影が投影されます。光の向きによって影の位置が変わります

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

壁・柱の影の投影

建築物や障害物がゲーム空間に存在する感覚を与えます。壁の形に沿ったOccluderPolygon2Dを作成し、LightOccluder2Dに割り当てるだけで、その壁の影がシーン全体に投影されます。

キャラクターの影

プレイヤーキャラクターやエネミーなどの動的なオブジェクトに対しても使用します。キャラクターの形に合わせたOccluderPolygon2Dを用意し、キャラクターが動くたびに同期させることで、常に正しい位置に影が落ちます。

洞窟の暗い領域

洞窟内では、光が遮られた領域が暗くなります。洞窟の形をLightOccluder2Dで定義することで、洞窟内外で照度が大きく異なる演出が可能です。

ランタンの光を遮る障害物

PointLight2Dで表現したランタンの光が、LightOccluder2Dを遮ってその背後に影を落とします。動的な影で、ゲーム空間の相互作用がより豊かになります。

別のノードが適切な場面

Shadow2D(Godot 4.3以降)は、より簡単な影表現に使用します。CanvasItemself_modulateで暗くするのは、影ではなく単なる色変更です。物理的な影が必要な場面では、LightOccluder2Dを選びましょう。

主なプロパティと機能

プロパティ名 説明 デフォルト値
occluder OccluderPolygon2D 影を投影する形状を定義。多角形で複雑な形も表現可能 null
sdf_collision bool Signed Distance Field衝突を使用するか。複雑な形状で有効 false
occluder_light_mask int どのLight2Dの光を遮るか。ビットマスクで複数の光に対応可能 1

GDScriptコード例1:動的なキャラクター影の同期

extends CharacterBody2D

@onready var sprite = $Sprite2D
@onready var light_occluder = $LightOccluder2D
var speed = 200.0

func _ready():
	# OccluderPolygon2Dをあらかじめ作成しておく
	# または、スクリプトで動的に生成することも可能
	pass

func _physics_process(delta):
	# キャラクターの移動
	var input_vector = Vector2.ZERO
	if Input.is_action_pressed("ui_right"):
		input_vector.x += 1
	if Input.is_action_pressed("ui_left"):
		input_vector.x -= 1
	if Input.is_action_pressed("ui_down"):
		input_vector.y += 1
	if Input.is_action_pressed("ui_up"):
		input_vector.y -= 1

	input_vector = input_vector.normalized()
	velocity = input_vector * speed
	move_and_slide()

	# LightOccluder2Dの位置・回転をキャラクターに同期
	light_occluder.global_position = global_position
	light_occluder.rotation = rotation

	# キャラクターがスプライトをフリップするなら、LightOccluderも同じようにスケール変更
	if input_vector.x < 0 and sprite.flip_h == false:
		sprite.flip_h = true
		light_occluder.scale.x = -1.0
	elif input_vector.x > 0 and sprite.flip_h == true:
		sprite.flip_h = false
		light_occluder.scale.x = 1.0

GDScriptコード例2:複数のLight2Dに対応した選択的な影投影

extends Node2D

@onready var directional_light = $DirectionalLight2D
@onready var point_light = $PointLight2D
@onready var light_occluder = $LightOccluder2D

func _ready():
	# light_occluderのoccluder_light_maskを設定
	# ビット0(値1)= DirectionalLight2D
	# ビット1(値2)= PointLight2D
	# ビット0とビット1両方に対応:mask = 3 (1 + 2)
	light_occluder.occluder_light_mask = 3  # 両方の光を遮る

func toggle_directional_light_occlusion():
	# DirectionalLight2Dからの影投影をオン/オフ
	var current_mask = light_occluder.occluder_light_mask
	if current_mask & 1:  # ビット0がセットされているか
		light_occluder.occluder_light_mask = current_mask & ~1  # ビット0をクリア
	else:
		light_occluder.occluder_light_mask = current_mask | 1  # ビット0をセット

func toggle_point_light_occlusion():
	# PointLight2Dからの影投影をオン/オフ
	var current_mask = light_occluder.occluder_light_mask
	if current_mask & 2:  # ビット1がセットされているか
		light_occluder.occluder_light_mask = current_mask & ~2  # ビット1をクリア
	else:
		light_occluder.occluder_light_mask = current_mask | 2  # ビット1をセット

func _process(delta):
	if Input.is_action_just_pressed("ui_select"):
		toggle_directional_light_occlusion()
	if Input.is_action_just_pressed("ui_cancel"):
		toggle_point_light_occlusion()




様々なOccluderPolygon2Dの形状
左から四角形、複雑な多角形、キャラクターシルエット。どのような形状でも影として投影されます

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

カスタマイズ項目 設定方法 効果
OccluderPolygon2Dの動的生成 var polygon = OccluderPolygon2D.new()
polygon.polygon = PackedVector2Array([...])
light_occluder.occluder = polygon
実行時にスクリプトで複雑な形状を生成可能。アニメーションと組み合わせて動的な影を実現
SDF衝突の有効化 light_occluder.sdf_collision = true 複雑な形状でも高速に衝突判定を実行。ただしメモリ使用量が増加
スケールと回転による影の変形 light_occluder.scale = Vector2(2.0, 1.0)
light_occluder.rotation = PI / 4
LightOccluder2D自体をスケール・回転することで、影の大きさや方向を動的に変更
LayerとMaskによる制御 light_occluder.light_mask = 0b0001
light_occluder.layer = 1
複数のLight2Dがある場合、特定の光だけに対応する影を設定可能
VisibleRectの活用 var rect = light_occluder.get_node("OccluderPolygon2D").get_bounding_rect()
print(rect)
影の範囲を取得し、パフォーマンス最適化やデバッグに活用

まとめ

LightOccluder2Dは、Godot 4の2D照明システムの中核をなすノードです。うまく活用すれば、見た目がフラットな2Dゲームでも、奥行きのある立体的な世界を表現できます。影の角度や濃淡を調整することで、プレイヤーに「そこに物体がある」という現実感を与えることができるのです。

  • LightOccluder2Dは光を遮り、その背後に影を投影するノード
  • OccluderPolygon2Dで形状を定義し、複雑な形状にも対応可能
  • キャラクターや動的なオブジェクトに対しても、位置と回転を同期させることで常に正確な影を表現

次回は、LightOccluder2Dと組み合わせてゲーム背景の奥行きを表現するParallaxBackgroundについて解説します。

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

このシリーズは、Godot 4でよく使用されるノードの使い方を詳しく解説しています。

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


コメント