マニュアル:弾幕(BarrageBullet)システム

概要

弾幕システム は、専用の実行アクション 「弾幕発射(FireBarrageBullet)」 を使用して、最小限の機能しか持たない非常に軽量な弾を発射するシステムです。

このシステムでは一度に数百発の弾を発射できますが、機能は非常に制限されています。弾に可視化スクリプトを設定したり、アニメーションを適用したりすることはできません。

弾幕との接触は、専用の条件 「弾幕と接触(CollideWithBarrageBullet)」 でのみ検出可能で、従来の攻撃判定や壁判定では検出できません。

複雑な挙動が必要な弾については、従来の 「弾発射」 アクションを使用してください。

「弾幕発射」で実現可能な機能

  • 発射タイプとして 全方位連射散弾 から選択できます。
  • 発射位置を指定できます。
  • 発射対象を指定できます。
  • 発射後の挙動として 直線曲線方向変更分裂追尾 から選択できます。
  • 弾のスプライトを指定できます。
  • 弾は 0度(右向き) を正面として、移動方向に応じて自動で回転します。
  • 弾の速度を指定でき、発射後に加速または減速させることも可能です。
  • 判定サイズと衝突レイヤーを指定できます。
  • 弾の攻撃力と属性を指定できます(ただし、自動でダメージ処理は行われないため、手動で設定する必要があります)。

「弾幕モード」の生成例

「花形パターン」

複数の 「全方位」+「曲線弾」 を同時に生成します。
曲線角度を反対の値に設定(例:片方を +0.3度、もう片方を –0.3度)することで、美しい花形パターンを描画できます。

さらに回転効果を加えると、洗濯機のようなパターンになります。

「格子パターン」

複数の 「連射」+「直線」 弾を使用し、発射位置のオフセットをずらして設定します。
方向変更や分裂効果を加えるとより面白くなります。

「自機狙い」

対象をプレイヤーに設定します。
オフセットを設定することで「自機外し弾」を実現でき、追尾を加えると予測射撃のような効果が得られます。

弾幕とスクリプト

弾幕システムで生成された弾にはスクリプトを設定できません。

そのため、「弾幕と接触」 条件を使用して、接触が発生した側のオブジェクト のスクリプト内で様々な挙動を実装する必要があります。

「弾幕と接触」で実現可能な機能

  • オブジェクトの HitArea と弾幕の判定との接触を検出できます。
    HitArea2D のレイヤーマスク弾幕のレイヤー が一致している場合に検出可能です。
  • 接触時に弾幕を削除できます(爆弾や被弾判定に頻繁に使用)。
  • 弾幕を削除する際、指定された確率で他のオブジェクトや Godot シーンに変換できます(主に爆弾効果に使用)。
  • 接触した弾幕の 攻撃力属性 を指定された変数に保存できます。

「弾幕と接触」の実用例

「爆弾」

HitArea を持つゲームオブジェクトを作成し、そのレイヤーマスクを弾幕のレイヤーと一致させることで、爆弾の攻撃判定範囲と同等にします。
このステップは少し複雑です。なぜなら、AttackArea では弾幕接触を検出できないためです。

可視化スクリプトで HitArea を爆発の瞬間のみ有効にし、その後消去します。爆発後、「接触した弾幕を削除」 オプションを有効にした 「弾幕と接触」 条件を設定します。

  • 爆弾が弾幕を削除した後にスコアアイテムを生成する場合
    ドロップアイテムを指定してください。この変換処理の負荷は通常のゲームオブジェクト生成と同程度のため、大量のオブジェクトを同時に生成するとパフォーマンスが低下します。
    ドロップ確率は低めに設定することを推奨します(例:10%)。
  • 爆弾が同時に敵にダメージを与える場合
    通常のダメージ処理を同時に実行するだけでよく、AttackArea2D と攻撃力を設定すればOKです。

「擦弾(Grazing)」

擦弾処理 専用のゲームオブジェクトを作成し、子ノードとして使用します。

  • 擦弾オブジェクトの設定
    親オブジェクトより大きな HitArea を設定します。
    可視化スクリプトで、「弾幕と接触」 がトリガーされたときに擦弾アニメーションやパーティクルエフェクトを再生し、スコアを加算するなどの処理を行います。

「弾幕のダメージ / 属性処理」

標準のダメージシステムを使用できないため、手動で設定する必要があります。

以下のように:

  • 弾幕ダメージ変数A に保存
  • 弾幕属性変数B に保存
  • 単純にダメージを与える場合
    ダメージ処理ステートで、「HP を変数Aの値だけ減少」 などの処理を設定します。
  • 属性によって異なる効果を発生させる場合
    ステート遷移条件で 「変数B が指定値と等しい」 と設定して、分岐処理を行います。

GDScript で弾幕を生成する

弾幕マネージャー(Barrage Manager)API に、弾丸の移動や動作を設定するクラスを渡すことで、弾幕を生成できます。

例:
36度 の間隔で全方向に弾丸を発射し、発射後5秒で消滅する弾幕。

# 弾丸のコマンドリストを作成(5秒後に消滅)
var vanish_command = BarrageBulletVanishCommand.new()
var wait_command = BarrageBulletWaitCommand.new()
wait_command.wait_time = 5

# コマンドリストを弾丸アクションデータに割り当て
var bullet_action_data = BarrageActionData.new()
bullet_action_data.command_list = [wait_command, vanish_command]

# 弾丸データを作成
var bullet_data = BarrageBulletData.new()
bullet_data.action_list = [bullet_action_data]
bullet_data.image_path = "res://〇〇.png"
bullet_data.speed = 100

# 全方向に発射する弾幕データを作成
# 発射コマンド
var fire_command = BarrageBulletFireCommand.new()
fire_command.bullet_data = bullet_data

# 方向データ
var direction_data = BarrageBulletDirectionData.new()
direction_data.direction_type = 3 # 前回発射した角度を参照(BulletML の SEQUENCE に相当)
direction_data.angle = 36         # 弾丸間の角度間隔

# 方向データを発射コマンドに割り当て
fire_command.fire_direction_data = direction_data

# 繰り返しコマンドに渡すアクションデータを作成
var repeat_command_action = BarrageActionData.new()
repeat_command_action.command_list = [fire_command]

# 10回繰り返す繰り返しコマンドを作成
var repeat_command = BarrageBulletRepeatCommand.new()
repeat_command.action_data = repeat_command_action
repeat_command.repeat_num = 10

# 弾幕発射コマンドリストを作成
var barrage_command_list = [repeat_command]

# マネージャーに渡すアクションデータ
var action_data = BarrageActionData.new()
action_data.command_list = barrage_command_list

# データを弾幕マネージャーに渡す
BarragesManager.fire_barrage([action_data])