Godot 4 で 2D ゲームの「魔法エフェクト」を作るとき、AnimationPlayer でスプライトをパラパラ漫画する方法で済ませがちです。けれどパーティクルを使えば、同じ作業時間で 10 倍リッチに見えるエフェクトが作れます。
この記事では GPUParticles2D を使った魔法エフェクトの実装テクニックを 3 つ紹介します。コードは Godot 4.4 以降で動作確認済みです。
前提: GPUParticles2D の基本
GPUParticles2D は GPU 上でパーティクルを処理するノードです。CPUParticles2D より 10〜100 倍速いので、数千個のパーティクルでも 60FPS を維持できます。
最小構成はこれだけ:
# シーン構造
GPUParticles2D
└── ProcessMaterial: ParticleProcessMaterial
└── Texture: 32x32 の白い円
エディタ上で GPUParticles2D ノードを追加し、ProcessMaterial に New ParticleProcessMaterial を作成、Texture にパーティクルの形を設定すれば動きます。
テクニック 1: 火の玉エフェクト(放射状の上昇パーティクル)
魔法といえば火の玉。基本は「下から上に放出 + ランダムな広がり」です。
extends GPUParticles2D
func _ready():
amount = 50
lifetime = 1.0
one_shot = false
var mat = ProcessMaterial.new()
# 上方向に放出
mat.direction = Vector3(0, -1, 0)
mat.spread = 30.0 # 30度の広がり
# 速度
mat.initial_velocity_min = 80.0
mat.initial_velocity_max = 120.0
# 重力で減速
mat.gravity = Vector3(0, 50, 0)
# 色: 黄→赤→透明
var grad = Gradient.new()
grad.add_point(0.0, Color(1, 1, 0.4, 1))
grad.add_point(0.5, Color(1, 0.4, 0.0, 1))
grad.add_point(1.0, Color(0.5, 0, 0, 0))
mat.color_ramp = GradientTexture1D.new()
mat.color_ramp.gradient = grad
process_material = mat
ポイントは color_ramp と scale_curve の組み合わせです。色をパーティクルのライフタイムに沿ってグラデーションさせると、火炎独特の「黄から赤に冷えていく」感じが出ます。
テクニック 2: 回復オーラ(円形に内向きに集まるパーティクル)
回復系の魔法は「外から中心に集まる」動きが定番です。emission_shape を EMISSION_SHAPE_RING にして、初速をマイナスに設定すれば実現できます。
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_RING
mat.emission_ring_radius = 80.0
mat.emission_ring_inner_radius = 70.0
mat.emission_ring_height = 0.0 # 2D なので 0
mat.emission_ring_axis = Vector3(0, 0, 1)
# 初速をマイナスにして中心に向かう
mat.initial_velocity_min = -60.0
mat.initial_velocity_max = -100.0
mat.flatness = 1.0 # 2D 平面に固定
# 色: 緑のグロー
var grad = Gradient.new()
grad.add_point(0.0, Color(0.4, 1.0, 0.4, 0))
grad.add_point(0.3, Color(0.4, 1.0, 0.4, 1))
grad.add_point(1.0, Color(0.8, 1.0, 0.8, 0))
mat.color_ramp = GradientTexture1D.new()
mat.color_ramp.gradient = grad
EMISSION_SHAPE_RING は本来 3D 用ですが、emission_ring_height = 0 にすれば 2D 平面でも使えます。flatness = 1.0 を設定するのを忘れずに。
テクニック 3: 雷エフェクト(瞬間的な強発光 + 減衰)
雷は「短時間に大量のパーティクル + 強い発光」で表現します。one_shot = true と explosiveness = 1.0 の組み合わせがポイント。
amount = 200 # 多めに
lifetime = 0.3 # 短い
one_shot = true # 一回だけ
explosiveness = 1.0 # 全部同時に放出
var mat = ProcessMaterial.new()
mat.direction = Vector3(0, 0, 0)
mat.spread = 180.0 # 全方向
mat.initial_velocity_min = 200.0
mat.initial_velocity_max = 400.0
# 発光のために CanvasItemMaterial を別途設定
var canvas_mat = CanvasItemMaterial.new()
canvas_mat.blend_mode = CanvasItemMaterial.BLEND_MODE_ADD
material = canvas_mat
BLEND_MODE_ADD がポイントです。重なったパーティクルが加算合成されるので、ぶつかり合うところが白く飛んで「閃光」になります。
呼び出すときは:
$ThunderParticles.restart() # 一瞬で全パーティクル放出
デバッグの罠: パーティクルが見えないときのチェックリスト
-
emitting = trueか? デフォルトは true ですが、コードで false にしていないか確認。 -
textureが設定されているか? Texture が空だと何も描画されません。 -
amount > 0か? デフォルト 8 ですが、one_shotで 0 になることがあります。 -
画面外で発生していないか?
positionが (0,0) のままで親が画面外にあるパターン。 -
local_coordsの挙動。 false (デフォルト) だと親の transform を継承しません。
特に 5 番は重要で、プレイヤーキャラクターから魔法を発射するときは local_coords = false にして、発射時の position を保存しておく必要があります。
まとめ
GPUParticles2D は使い始めの学習コストはありますが、一度パターンを覚えると 10 分で見栄えするエフェクトが作れるようになります。今回紹介した 3 パターン:
| エフェクト | 主な設定 | 用途 |
|---|---|---|
| 火の玉 |
color_ramp + 上向き放出 |
攻撃魔法、トーチ |
| 回復オーラ |
EMISSION_SHAPE_RING + 負の初速 |
回復、シールド |
| 雷 |
one_shot + explosiveness=1.0 + BLEND_MODE_ADD
|
爆発、ヒット、閃光 |
これらをベースに、テクスチャを変えたり色を変えたりするだけで、十数種類のエフェクトが作れます。