概要
アクションゲームにおいて、プレイヤーが敵に攻撃を当てたときや、逆にダメージを受けたときの「手応え」は、ゲームの爽快感を大きく左右する重要な要素です。その手応えを演出する最もシンプルかつ効果的なテクニックの一つが、キャラクターが一瞬白く光るホワイトフラッシュ です。
Godotでは、このホワイトフラッシュ効果を、シェーダーなどの難しい知識を使わずに、たった数行のコードとTweenノードで簡単に実装できます。その鍵となるのがmodulateプロパティです。

modulateプロパティの仕組み
modulateは、CanvasItemを継承するすべての2Dノード(Sprite2D, Label, ColorRectなど)が標準で持っているプロパティです。このプロパティにColorを設定することで、そのノード(およびそのすべ ての子ノード)の色合いを乗算で変化させることができます。
modulate = Color(1, 1, 1)(白): 元の色と全く同じ(デフォルト状態)modulate = Color(1, 0, 0)(赤): テクスチャのR成分のみが残り、赤みがかるmodulate = Color(0.5, 0.5, 0.5)(グレー): 全体的に暗くなるmodulate = Color(1, 1, 1, 0.5)(半透明): アルファ値で透明度を操作できる
なぜ白く光るのか? HDR(ハイダイナミックレンジ)効果
modulateプロパティの最も興味深い特徴は、色の値を1以上に設定できる点です。通常、色は0(光なし)から1(元の色)の範囲で表現されますが、modulateのRGB値を1以上にすると、そのスプライトはHDR(ハイダイナミックレンジ)カラーとして扱われ、まるで内側から発光しているかのように輝き始めます。これが「白飛び」したような表現になり、ホワイトフラッシュの原理となります。
例えば、modulate = Color(10, 10, 10) のように非常に大きな値を設定すると、元のテクスチャの色に関わらず、スプライトはほぼ真っ白に光ります。
基本的な実装:Tweenで滑らかに変化させる
ホワイトフラッシュは、「一瞬で白くなり、すぐに元の色に滑らかに戻る」という一連のアニメーションです。このような時間経過を伴う処理を実装するために、GodotにはTweenという非常に強力で便利な機能が用意されています。
以下は、ダメージを受けたキャラクター(spriteという名前のSprite2Dを持つノード)にホワイトフラッシュを適用する、汎用的な関数の例です。
# CharacterBody2Dなどのスクリプト
# Tweenをインスタンス変数で管理(連続ダメージ時の制御用)
var flash_tween: Tween
# ダメージを受けた時に外部から呼び出す関数
func apply_damage_effect():
# ... HPを減らす、無敵時間を開始するなどの処理 ...
# ホワイトフラッシュ処理を開始
_start_white_flash()
# ホワイトフラッシュを実行する内部関数
func _start_white_flash():
# すでに実行中のTweenがあればキャンセルする
if flash_tween and flash_tween.is_valid():
flash_tween.kill()
# 1. スプライトを一瞬で白くする
$Sprite2D.modulate = Color(10, 10, 10) # 大きな値で白く輝かせる
# 2. Tweenを作成して、元の色に滑らかに戻すアニメーションを作る
flash_tween = create_tween().set_trans(Tween.TRANS_QUINT).set_ease(Tween.EASE_OUT)
# 0.3秒かけて、$Sprite2DのmodulateプロパティをColor(1, 1, 1)まで変化させる
flash_tween.tween_property($Sprite2D, "modulate", Color(1, 1, 1), 0.3)
コードの解説
flash_tweenというインスタンス変数でTweenを管理します。これにより、連続してダメージを受けた際に、前のTweenをキャンセルして新しいフラッシュを開始できます。_start_white_flash関数が呼ばれると、まず$Sprite2D.modulateを非常に大きな値を持つColorに設定します。これにより、スプライトは即座に白く光ります。create_tween()で新しいTweenオブジェクトを作成します。ここではメソッドチェーンでset_transとset_easeを使い、アニメーションの緩急(イージング)を設定しています。TRANS_QUINTとEASE_OUTの組み合わせは、素早く始まりゆっくり終わる、メリハリのある動きになります。tween_property()がアニメーションの核となる部分です。このメソッドは「どのオブジェクト」の「どのプロパティ」を「どの値」に「どのくらいの時間」で変化させるかを指定します。Tweenは作成されると自動的に再生され、完了すると自動的に破棄されるため、これだけで実装は完了です。
注意:
Color(10, 10, 10)のような大きな値が効かない場合は、プロジェクト設定でHDRが無効になっている可能性があります。その場合はColor(2, 2, 2)〜Color(3, 3, 3)程度の値から試してみてください。
よくある間違いとベ ストプラクティス
modulateを使った演出は簡単ですが、より洗練されたコードにするためのポイントがいくつかあります。初心者が陥りがちな間違いと、推奨される設計を比較してみましょう。
| よくある間違い | ベストプラクティス |
|---|---|
_process内でカウンター変数を使って自力でアニメーションさせる | TweenやAnimationPlayerを使い、宣言的にアニメーションを記述する |
modulateの値を直接Color(0,0,0)にしてしまい、黒くなる/消える | 白く光らせるにはRGB値を1より大きくする。黒くしたい場合もColor(0,0,0)ではなくColor(0.1, 0.1, 0.1)のように少し明るさを残すと質感が良い |
| ダメージ処理とエフェクト処理が同じ関数に混在している | Signalを使い、ダメージ判定ロジックと視覚エフェクトを分離する。これにより、エフェクトの変更がロジックに影響しなくなる |
エフェクトのたびにcreate_tween()を呼び出しっぱなしにする | 短時間に連続してエフェクトが発生する場合、既存のTweenをkill()してから新しいTweenを作成すると、意図しない動作を防げる |
代替パターンとの比較
ホワイトフラッシュを実装する方法はmodulateだけではありません。代表的な代替手法であるシェーダーとの比較を見てみましょう。
| 特徴 | modulate + Tween | カスタムシェーダー |
|---|---|---|
| 手軽さ | ◎ 非常に簡単。数行のGDScriptで実装可能 | △ シェーダー言語(Godot Shader Language)の学習が必要 |
| パフォーマンス | ○ 非常に軽量。多数のオブジェクトでも問題になりにくい | ◯〜△ シェーダーの複雑さによる。シンプルなものは軽量だが、複雑なものは高負荷になりうる |
| 表現力 | △ 色の乗算とアルファ値の変更のみ。限定的 | ◎ 無限大。アウトライン、ディゾルブ、発光など、あらゆる視覚効果をピクセル単位で制御可能 |
| おすすめの用途 | ダメージフラッシュ、アイテム取得時の発光など、シンプルな演出 | ボスキャラクターの特殊な登場演出、独自のパーティクル表現など、凝った視覚効果 |
ほとんどのダメージフラッシュ表現においては、手軽さとパフォーマンスの観点からmodulateとTweenの組み合わせが最適解と言えるでしょう。
まとめと次のステップ
この記事では、GodotのmodulateプロパティとTweenノードを使い、ホワイトフラッシュ効果を実装する方法を解説しました。このテクニックは、プレイヤーに明確なフィードバックを与え、ゲームの爽快感を向上させるための、費用対効果が高い手法の一つです。
modulate:CanvasItemの色を乗算で変更するプロパティ。値を1以上にするとHDR効果で白く光る。Tween: プロパティを時間経過で滑らかに変化させるための強力なツール。
このシンプルながらも奥深いテクニックをマスターしたあなたは、次に以下のようなトピックに挑戦してみることをお勧めします。
- サウンドエフェクトの追加: ホワイトフラッシュと同時に短い効果音を再生することで、フィードバックが格段にリッチになります。
AnimationPlayerの活用: 点滅、色の変化、揺れなど、複数のアニメーションを組み合わせた複雑なシーケンスを管理するのに適しています。- シェーダー入門:
modulateでは物足りなくなったら、シェーダーの世界に足を踏み入れてみましょう。キャラクターの輪郭を光らせたり、ノイズをかけたりと、表現の幅が無限に広がります。