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

Node解説

はじめに

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を選びましょう。

主なプロパティと機能

プロパティ名説明デフォルト値
occluderOccluderPolygon2D影を投影する形状を定義。多角形で複雑な形も表現可能null
sdf_collisionboolSigned Distance Field衝突を使用するか。複雑な形状で有効false
occluder_light_maskintどの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 / 4LightOccluder2D自体をスケール・回転することで、影の大きさや方向を動的に変更
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.xをもとに執筆しています。

コメント