概要
Godot Engineで制作する2Dゲームにおいて、ライティングは単なる装飾以上の役割を果たします。適切に設定された光と影は、シーンに深みと雰囲気を与え、プレイヤーの注意を誘導し、ゲームの世界観を向上させます。
この記事では、Godotの2Dライティングシステムの核となるPointLight2Dノードと、それを使った**影(シャドウ)**の設定方法に焦点を当て、初心者が陥りやすいポイントを解消しながら、実践的なベストプラクティスを解説します。
2Dライティングの基本要素
Godotの2Dライティングは、主に3つのノードの連携によって機能します。
| 要素 | 代表的なノード | 役割 |
|---|---|---|
| 光源 | PointLight2D, DirectionalLight2D | シーンに光を放つ存在。点光源や平行光源など、光の種類を決定します。 |
| 遮蔽物 | LightOccluder2D | 光を遮り、影を生成するための形状を定義します。物理的な衝突判定とは独立しています 。 |
| 被写体 | Sprite2D, TileMap など | CanvasItem を継承する全てのノード。光の影響を受け、照らされたり影の中に隠れたりします。 |
PointLight2Dの仕組み
PointLight2D は、指定した一点から全方位に光を放射する、最も基本的な光源です。この光の形状や色は、インスペクタのプロパティで細かく調整できます。
- Enabled: この光源を有効化/無効化します。
- Texture: 光の形状と減衰を定義するテクスチャ。通常は中心が白く、外側に向かって黒くフェードアウトする放射状のグラデーション (
GradientTexture2D) を使用します。 - Color: 光の色。
#FFFFFF(白) がデフォルトです。 - Energy: 光の強度。値が大きいほど明るくなります。
- Shadow > Enabled: この光源が影を生成するかどうかを決定します。パフォーマンスに影響するため、必要な光源でのみ有効にしましょう。
ヒント:
PointLight2Dをシーンに追加したら、まずインスペクタでTextureプロパティの[空]をクリックし、[新規 GradientTexture2D]を選択します。次に、表示されたGradientTexture2Dをクリックし、FillをRadialに変更するだけで、基本的な光源テクスチャが完成します。
影を生み出す境界: LightOccluder2D
影は自動では生成されません。Godotに対して「何が光を遮るのか」を教える必要があります。その役割を担うのが LightOccluder2D ノードです。
このノードは、壁、柱、キャラクターなど、影を落とさせたいオブジェクトの子ノードとして追加します。そして、Occluder プロパティに OccluderPolygon2D リソースを新規作成し、エディタ上部のツールバーから頂点を追加して、光を遮るための多角形を描画します。
よくある間違いとベストプラクティス
2Dライティングの設定は直感的ですが、いくつかの落とし穴も存在します。
| 間違い(アンチパターン) | 問題点 | 解決策(ベストプラクティス) |
|---|---|---|
LightOccluder2D を使わない | PointLight2D の Shadow > Enabled をオンにしても、遮蔽物が定義されていないため影が一切生成されない。 | 影を落としたい全てのオブジェクト(またはその親)に LightOccluder2D を追加し、OccluderPolygon2D で遮蔽範囲を正確に定義する。 |
CanvasModulate を黒にする | シーン全体が真っ黒になり、光源の当たっている部分しか見えなくなる。 | CanvasModulate の色は乗算ブレンドで適用され、Light2Dがない場所の色そのものになる。完全な暗闇ではなく、少し明るいグレー(例: #202020)などを設定し、最低限の視認性を確保する。 |
OccluderPolygon2D の頂点が多すぎる | 複雑なポリゴンは、毎フレームのシャドウ計算コストを増大させ、特にモバイルデバイスでパフォーマンスの低下を引き起こす。 | 遮蔽物の形状を表現できる、必要最小限の頂点でポリゴンを作成する。特に TileMap では、個々のタイルではなく TileSet エディタで Occlusion を設定し、エンジンに最適化させる。 |
| 全ての光源で影を有効にする | 装飾目的の小さな光や、パフォーマンスが重要でない光源まで影を計算してしまい、不要な負荷がかかる。 | プレイヤーのゲームプレイに直接影響する重要な光源(例: 懐中電灯、主要な街灯)でのみ影を有効にし、雰囲気作りのための補助的な光では Shadow > Enabled をオフにする。 |
Light Mask を活用しない | 全ての光が全てのオブジェクトに影響するため、意図しないライティングが発生したり、パフォーマンスの最適化機会を逃したりする。 | Range > Item Cull Mask (光源側) と Visibility > Light Mask (オブジェクト側) を使い、ライティングのレイヤー分けを行う。 |
GDScriptによる動的なライティング制御
GDScript を使って光を動的に制御することで、ゲームはよりインタラクティブになり ます。
懐中電灯の実装例
プレイヤーに追従し、エネルギー管理を持つ懐中電灯の例です。
# Player.gd (子ノードに "Flashlight" という名前の PointLight2D を持つことを想定)
extends CharacterBody2D
@onready var flashlight: PointLight2D = $Flashlight
@export var max_light_energy: float = 1.0
@export var energy_drain_rate: float = 0.02 # 1秒あたりのエネルギー消費量
var current_energy: float
func _ready() -> void:
current_energy = max_light_energy
flashlight.enabled = false
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("toggle_light"):
flashlight.enabled = not flashlight.enabled
get_viewport().set_input_as_handled()
func _process(delta: float) -> void:
if not flashlight.enabled:
return
# エネルギーを徐々に減少させる
current_energy -= energy_drain_rate * delta
if current_energy <= 0.0:
current_energy = 0.0
flashlight.enabled = false
# エネルギー残量に応じて光の強さを変える
flashlight.energy = lerp(0.5, 1.5, current_energy / max_light_energy)
# 懐中電灯をマウスカーソルの方向に向ける
# 注意: PointLight2Dは放射状に光を放つため、回転しても見た目は変わりません。
# 扇形の懐中電灯効果を出すには、Textureを扇形のグラデーション画像にする必要があります。
var mouse_pos = get_global_mouse_position()
flashlight.rotation = (mouse_pos - global_position).angle()
# エネルギーを回復する関数
func restore_energy(amount: float) -> void:
current_energy = min(current_energy + amount, max_light_energy)
if not flashlight.enabled and current_energy > 0:
flashlight.enabled = true
DirectionalLight2D との比較
PointLight2D が点光源であるのに対し、DirectionalLight2D は太陽光や月光のように、シーン全体に一方向から降り注ぐ平行光源です。
| 特徴 | PointLight2D | DirectionalLight2D |
|---|---|---|
| 光の形状 | 点から放射状に広がる | シーン全体に平行に降り注ぐ |
| 主な用途 | 松明、電球、魔法の光など、特定の場所にある光源 | 太陽光、月光、屋外の環境光 |
| 影の挙動 | 光源の位置に基づいて、全方向に影が伸びる | 光の角度に基づいて、一方向に影が伸びる |
| パフォーマンス | 多数配置すると負荷が高まりやすい | 通常はシーンに1つか2つ使用。比較的軽量。 |
使い分けのヒント: 屋外シーンでは、まず DirectionalLight2D で全体の明るさと影の方向を決め、その上で洞窟の入り口やキャンプファイアなどに PointLight2D を補助的に配置すると効果的です。
まとめ
Godotの2Dライティングは、PointLight2DとLightOccluder2Dの組み合わせを理解することが成功の鍵です。
- PointLight2D: 光源そのもの。テクスチャとエネルギーで光の見た目を調整します。
- LightOccluder2D: 影を落とすための境界。影を生成するには必須のノードです。
これらの基本をマスターすれば、2Dゲームは単調な平面表現から、光と影が織りなす深みのある世界へと進化するでしょう。次に学ぶべきステップとしては、**法線マップ(Normal Map)**を使ったよりリアルなライティング表現や、カスタムシェーダーによる光の表現の拡張がおすすめです。