他のオブジェクトとの距離の判定

■前提
プレイヤーは画面左側、敵キャラクターは画面右側で左を向いています
敵のVSを以下で設定
待機 → 攻撃 → 待機(ショートカット)
待機 → 攻撃 距離が128以内だったら
攻撃 → 待機 攻撃アニメーションが終了したら

・他のオブジェクトとの距離
・方向を指定: このオブジェクトと同じ方向 または 方向を指定で:left_arrow: のみ指定
・距離: 128
・距離条件: より近く
・対象の種類: オブジェクト
・対象オブジェクトの種類: オブジェクト
・対象オブジェクトのパス: プレイヤーのtscnを指定
・対象とするオブジェクトの位置: 最も近いオブジェクト

上記の条件の場合 128以内に入るとリンクしますが、敵の近くに行くとリンクしなくなります(32以内くらい?)

・方向を指定: :up_left_arrow: :left_arrow: :down_left_arrow:

方向を斜めも指定すると敵の近くであっても正常に動作します

これは仕様なのでしょうか?

確認したところ、こちらは仕様となります。

他のオブジェクトとの距離条件ですが、

  • 方向は8方向に45°ずつの扇形の判定範囲を生成する。
  • GameObjectの「原点」同士の位置で距離と方向は判定される。

という仕様になっております。

そのため、頭の頂点に原点が来るように制作したオブジェクト同士で、背の高さに大きく違いがある場合などは以下のような図の状態となり、「距離判定は満たすが左の範囲の外にでてしまう」という状態が発生します。

なので、オブジェクトの原点の位置を水平になるようにしていただくか、判定を左上、左下などにも設定することで問題の発生を避けることができます。

半径指定した円(と角度)での判定なのですね
仕様という事で理解しました
「攻撃判定との距離」も同様の仕様という事でよろしいでしょうか?

ちなみに単純なX位置(またはY位置)の比較という条件は無いのでしょうか?
例)ドッスンみたいに高低差がある状態で近づいたら落ちてくるみたいな事をしたい

VSでやろうとするとplayerのXに判定したい距離を加算 or 減算した変数を用意してループで毎回回して、enemyのXより大きい or 小さい で判定するのかと思いますが結構めんどくさいなぁと…

もしくは最近ついかされた「スクリプトで条件判定」を使うイメージでしょうか?
「スクリプトで条件判定」はまだ使ったことがないのですが、簡単な実装サンプルが欲しいです

攻撃判定との距離は確認します。

単純なX位置比較はないのですが、ご指摘の通り「スクリプトで条件判定」を使うことで解決することができます。

簡単なサンプルをお渡しします。

  1. 設定したいオブジェクトの子としてNode2Dを用意します。image

  2. Node2DにGDスクリプトをアタッチし、中身を以下で上書きします。以下の式は、Playerグループのオブジェクトが100以内に近づくとTRUEを返すメソッド”is_player_in_x_range”です。

    extends Node2D
    
    @export var attack_range := 100.0
    var player: Node2D
    
    func _ready():
    # グループ “Player” に登録されているオブジェクトを自動取得
    player = get_tree().get_first_node_in_group(“Player”)
    
    func is_player_in_x_range() → bool:
    if not player:
    return false
    
    # X座標の差だけを見て判定
    var diff_x = abs(global_position.x - player.global_position.x)
    return diff_x <= attack_range
    
  3. 「スクリプトで条件判定」で作成したNode2Dを指定し、メソッドとしてis_player_in_x_rangeを指定します。

「スクリプトを実行」「スクリプトで条件判定」は、このように、子ノードに添付されたGDScriptのメソッドを条件やアクションとして使うものになっています。

fucn~~~~となっているのがメソッドですね、このGDScriptに続けてメソッドを増やしていくことで色々なメソッドを使い分けたりすることができます。

1 Like

ありがとうございます!
めっちゃ同じ感じでGDScript書いてる所でしたw
リンクでの条件判定はメソッドからbool値返すように作ればいいのですね

ちょっと違うやり方で実行アクションの方で常にメソッド回してx距離,y距離を保持したいと思ってるのですが
GameObjectのVariableSettingsでユーザー作成の変数に格納させたいのですが
GDスクリプトからだとどう指定すればいいでしょうか?

例) : distance_xという名前のユーザー作成変数に 値を代入したい

変数のデータを代入 $“VaribleSettings へのパス”.set_value(“変数名”, 代入したい値)

これで変数名を自分で定義した”distance_x”指定すればいいのかな?

そうですね~そちらでいけるとおもいます。

1 Like

いけました!ありがとうございます :folded_hands:

1 Like

攻撃判定との距離についても似たような形で、

「GameObject の原点」と「攻撃判定(AttackArea2D)のシェイプの原点」との距離

となるとのことでした。

1 Like