【機能追加の提案】同じ対象には衝突判定による攻撃を1回しか通さない(「同じ対象にはダメージを1回しか与えない」機能と併用)

問題分析:

  1. 発射する弾に「貫通攻撃」という強化可能なスキルを実装したいと考えています。

  2. 貫通回数を弾のHPで管理します。貫通できない状態ではHPは1、1回多く貫通できるごとにHPを+1します(貫通が発生した際にHPを-1します)。

  3. AGMバージョン1.2.3では、「同一対象に対して1回のみダメージを与える」という機能が追加されました。この機能を活用することで、弾が敵に衝突した際、同じ敵には1回しかダメージを与えず、弾が消滅しない場合は次の敵にダメージを与えられるという挙動を適切に実現できます。

  4. しかし、この機能だけでは弾の攻撃衝突の検知を完全に制御できません。例えば、弾が2回貫通できる場合、1回目の貫通でダメージを与え、2回目の貫通でもダメージを与えた後に弾が消滅させたいとします。もし「同一対象との衝突は1回のみ」といった衝突検知の制御機能がなければ、この弾が最初の敵に命中した際、ダメージは1回しか発生しなくても、衝突判定自体は継続的に発生してしまいます。

そのため、弾のHPを用いて「弾がX回だけ貫通する」という挙動を実現することができません。弾が敵に衝突して1回ダメージを与える制御はできても、連続して衝突し続けるため、HPは1回の攻撃あたり1回減るのではなく、継続的に減少してしまいます。

  1. つまり、以前の機能は「同一対象に1回のみダメージを与える」ことは解決しましたが、「同一対象に1回のみ攻撃判定を行う」という本質的な課題は解決できていません。

機能要望:

  1. AGM公式に、「同一対象に対して1回のみ攻撃判定を行う」という機能を追加していただき、既存の「1回のみダメージを与える」機能と連携させてほしいと考えています。
  2. 現時点でこの機能の追加が難しい場合、この機能を実現するための代替方法をご教示いただけますでしょうか。
「いいね!」 1

少し考えた後、シグナルとGDスクリプトでこの機能を実装しましたので、まず共有します。

(1)中核技術:Godotネイティブのシグナル検出「area_entered」(攻撃ヒットボックスから直接シグナルを発信し、GDスクリプトに送信)。
このシグナルは、特定のArea2D領域が範囲内に入った際に発火します。
メリット:領域が範囲内に入った際、シグナルは1回のみ送信されます。したがって、武器の攻撃範囲に敵Aが入っても、外に出ない限りシグナルは1回しか発火しません。その後、敵Bが入れば、引き続きシグナルを発火させることができます。2体の敵が検出範囲に入っても互いに干渉せず、結果として攻撃判定が絶えず繰り返されることを自然に防ぎます。
このシグナル内には、「敵グループ」が進入したときのみ発火するという条件を設定しています。

(2)貫通回数を管理する変数を作成することも可能です。ここではオブジェクトのHP値に直接バインドしており、AGMのオブジェクト属性設定上、体力が尽きた時点で自動的に消滅させるようにしています(非常に便利です)。

(3)シグナル発火後、貫通回数を1減らすだけで構いません。0になると武器は破棄されます。

中核コード(前提として、貫通回数をオブジェクトのHPにバインドしているため、HPを使用しない場合は任意の変数を宣言してください):
func _on_攻撃盒_area_entered(area: Area2D) → void:
var 貫通力 = 変数.get_value(“hp”)
if area.is_in_group(“Enemy”) :
貫通力 -= 1
変数.set_value(“hp”, 貫通力)

この件を解決したのは素晴らしいですね。

攻撃判定をターゲットごとに1回だけ実行するというオプションを、「ダメージを1回だけ受ける」設定と組み合わせた方が合理的だと考えます。

「いいね!」 1

BAZさん、ご返信ありがとうございます。公式が本機能をサポートしてくれれば、制作がはるかに楽になりますね!

「area_entered」シグナルを使って攻撃を検知するのは完璧ではなく、弾と敵がすれ違う際、ヒットボックスによる判定では敵が被弾したと認識されるのに、area_entered のシグナル受信ではその弾が敵に当たったと検知されないことがあります。そのため、この手法は実際のゲーム制作では小さなバグを伴うことになります。公式が関連する機能を追加してくれることを期待しています。当面は、弾が連続してダメージを受けるのを防ぐため、弾に一時的な無敵状態を付与する対応(これは消極的な治療策です)をとるしかありません。