攻撃を当てても、敵がダメージを受けた実感が薄い——アクションゲームで「手応え」が足りないと感じたことはないでしょうか。プレイヤーが敵を殴った瞬間、あるいは自分が被弾した瞬間に、キャラクターが一瞬パッと白く光る。たったこれだけで、打撃の気持ちよさは驚くほど増します。この演出が ホワイトフラッシュ です。
しかも実装はとても手軽で、シェーダーのような難しい知識は要りません。modulate プロパティと Tween を組み合わせれば、数行のGDScriptで作れます。
この記事でわかること
modulateが色を 乗算 で変える仕組み- RGB値を 1より大きく すると白く光るHDRの原理
Tweenで「一瞬白く → なめらかに戻す」を作る基本実装- シェーダーとの使い分けと、被弾リアクションへの組み込み方
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): 4つ目の値(アルファ)で半透明にできる
「元の色 × 指定した色」なので、1 を掛ければそのまま、0.5 を掛ければ暗く、というのがポイントです。

なぜ白く光るのか? HDR効果
modulate のおもしろいところは、RGB値を1より大 きく設定できる 点です。通常、色は0(光なし)〜1(元の色)で考えますが、modulate のRGBを1以上にすると、そのスプライトはHDR(ハイダイナミックレンジ)カラーとして扱われ、内側から発光しているように輝きます。これが「白飛び」した見た目になり、ホワイトフラッシュの正体です。
上の図の右端のように、modulate = Color(10, 10, 10) のような大きな値にすると、元のテクスチャの色に関係なく、スプライトはほぼ真っ白に光ります。この 「一瞬だけ大きな値にして、すぐ元に戻す」 がフラッシュ演出の核です。
基本の実装:Tweenで一瞬白くして戻す
ホワイトフラッシュは「一瞬で白くなり、すぐ元の色になめらかに戻る」という短いアニメーションです。この時間変化は Tween の得意分野です。

ダメージを受けたキャラクター(Sprite2D を持つノード)にフラッシュをかける 関数です。
# CharacterBody2Dなどのスクリプト
# 連続ダメージの制御用に、Tweenを変数で持っておく
var flash_tween: Tween
func apply_damage_effect() -> void:
# ... HPを減らす・無敵時間を始めるなどの処理 ...
_start_white_flash()
func _start_white_flash() -> void:
# すでにフラッシュ中なら止めてから始める(連続ヒット対策)
if flash_tween and flash_tween.is_valid():
flash_tween.kill()
# 1. まず一瞬で白くする(大きな値でHDR発光させる)
$Sprite2D.modulate = Color(10, 10, 10)
# 2. 0.3秒かけて元の色 Color(1,1,1) へなめらかに戻す
flash_tween = create_tween().set_trans(Tween.TRANS_QUINT).set_ease(Tween.EASE_OUT)
flash_tween.tween_property($Sprite2D, "modulate", Color(1, 1, 1), 0.3)
組み立てのコツは、 光らせる瞬間は代入で一発、戻すところだけTweenでなめらかに という点です。TRANS_QUINT + EASE_OUT は「パッと始まってスッと収まる」ので、フラッシュの余韻に向いています。連続でダメージを受けても、flash_tween.kill() で前のフラッシュを片付けてから始めるので破綻しません。
注意:
Color(10, 10, 10)にしても白く見えない場合、描画が色を1でクランプしていることがあります。まずColor(2, 2, 2)〜Color(3, 3, 3)程度から試してください。WorldEnvironmentの Glow を有効にすると、1を超えた分がふわっとにじんで、より発光らしくなります。
よくある間違いとベストプラクティス
modulate の演出は手軽ですが、いくつか押さえておくと安定します。特に 暗くしようとして真っ黒にしてしまう のは初心者がやりがちな失敗です。

| よくある間違い | ベストプラクティス |
|---|---|
_process 内でカウンター変数を使い、自力でアニメーションさせる | Tween や AnimationPlayer を使い、宣言的に書く |
暗くしようと Color(0, 0, 0) にして、真っ黒で消えてしまう | 白く光らせるならRGBを 1 より大きく。暗くしたい場合も Color(0.1, 0.1, 0.1) のように少し明るさを残す |
| ダメージ処理とエフェクト処理が同じ関数に混ざっている | シグナルでダメージ判定と視覚エフェクトを分離し、演出の変更がロジックに波及しないようにする |
エフェクトのたびに create_tween() を呼びっぱなしにする | 短時間に連続するなら、既存の Tween を kill() してから作り直す |
modulateとシェーダーの使い分け
ホワイトフラッシュはシェーダーでも作れます。手軽さ重視の modulate + Tween と、表現力重視のシェーダーを比べてみましょう。

| 特徴 | modulate + Tween | カスタムシェーダー |
|---|---|---|
| 手軽さ | ◎ 数行のGDScriptで実装できる | △ シェーダー言語の学習が必要 |
| パフォーマンス | ○ 非常に軽量。多数のオブジェクトでも問題になりにくい | ○〜△ シンプルなら軽量だが、複雑だと高負荷になりうる |
| 表現力 | △ 色の乗算とアルファ変更のみ。限定的 | ◎ アウトライン・ディゾルブ・発光などピクセル単位で自由 |
| 向いている用途 | ダメージフラッシュ、アイテム取得時の発光などシンプルな演出 | ボスの特殊な登場演出など、凝った視覚効果 |
ほとんどのダメージフラッシュは、手軽さと軽さから modulate + Tween で十分です。輪郭だけを光らせる、溶けるように消す、といった凝った表現が欲しくなったら Fragment Shaderの基礎 へ進みましょう。
実践:被弾リアクションを疎結合で組む
フラッシュ単体でも効果的ですが、実際のゲームでは「被弾したら、白フラッシュ+ノックバック+効果音がまとめて起きる」ことが多いはずです。
- アクション :敵を斬ると、その敵が白フラッシュしてのけぞる
- シューティング :弾が当たった機体が一瞬白く光り、被弾音が鳴る
- ローグライク :攻撃が当たるたびに対象がフラッシュして手応えを出す
ここで大事なのは、 ダメージのロジック(HPを減らす)と、見た目の演出(フラッシュ)を分ける ことです。分けておくと、同じ演出をプレイヤー・敵・破壊できる木箱などで使い回せます。橋渡しには シグナル を使います。
