
GODOT RigidBody2D vs 当たり判定
前回はリフティングをして遊びました。
今回は、当たり判定を使ってボールを弾こうと思います。
今回のAIアドバイザーは「Gemini2.0」と「ChatGPT」です。
今日のハイライト

キャラを作る
前回は距離を判定して範囲内のボールを押していましたが、距離だと範囲指定がしにくく見えないなど調整しにくい問題がありました。
今回は、距離ではなく、キー入力で当たり判定を出してボールを押したり蹴ったりします。アクションゲームではパンチやキックなどの攻撃に当たりをつけてぶっ飛ばす方がやりやすいっす。
Kicker
まずは、Kickerというプレイキャラを作っていきます。
プレイキャラの作り方
作り方は、「RigidBody2Dでボール遊び」の記事の「プレイヤーを作る」「ステージを作る」「キャラを動かす」までを参照してください。
※今回、ステージ名は「StageTest」にしました。
※「キャラがボールを押す機能を追加」以降は必要ありません。
StageTestの構成は以下のようにしました。
ボールが飛びすぎて画面外に行くのを防ぐため、Wallの高さを画面の2倍にして上にFloorを追加して天井をつけています。


この時点ではボールを動かせません。
キー入力を変更
プロジェクト設定のインプットマップで以下のようにキー入力を設定してコードを修正してください。(詳細はリフティングの記事を参照)

押し当たりを作る
まずは、左右キーで移動する時に押し当りを発生させてみます。
Area2Dというコリジョン用のノードを使って当たり判定を作ります。
押し当たりの設定
・ファイルシステムのKicker.tscnを選択。
・Kickerの子ノードにArea2Dを追加し、PushAreaに名前を変更
・Area2Dの子ノードにCollisionShape2Dを追加
・CollisionShape2DのインスペクターからCapsuleShapeを選ぶ
・CapsuleShapeのTransformのRotationを90度回転
・大きさや位置を調整して横長の楕円を作る。

押し当たりのスクリプト
押す力の数値を設定
・SPEEDやJUMP_VELOCITYの下に「PUSH_FORCE」という押す力を数値設定
const PUSH_FORCE = 200.0
左右キーで当たりを発生
・左右キーの入力を見て当たりを発生させます。
func _process(delta: float) -> void:
if Input.is_action_pressed("move_left") or Input.is_action_pressed("move_right"):
$PushArea.set_monitoring(true) # 攻撃範囲を有効にする
else:
$PushArea.set_monitoring(false) # 攻撃範囲を無効
押し当たりからシグナルを受信
・PushAreaシーンをクリック
・インスペクターをノードタブに変更
・シグナルからbody_enteredをダブルクリックしKickerスクリプトへ接続

コードを追加
・スクリプトの最後に、func _on_push_area_body_enteredが張り付けられる
※行番号の左に緑色のアイコンが追加されたことを確認
・「pass」以降を以下のコードに変更
func _on_push_area_body_entered(body: Node2D) -> void:
if body is RigidBody2D and Input.is_action_pressed("move_right"):
# 攻撃処理
print("右がヒット")
body.apply_impulse(Vector2(PUSH_FORCE, 0)) # 例: 相手に衝撃を与える
elif body is RigidBody2D and Input.is_action_pressed("move_left"):
# 攻撃処理
print("左がヒット")
body.apply_impulse(Vector2(-PUSH_FORCE, 0)) # 例: 相手に衝撃を与える
押す
左右キーの入力中、押し当たりが有効になり押せるようになりました。

ヘディングを作る
ジャンプ中のヘディング用の当たりを作ります。
作り方は、押し当たりと一緒なのでそちらを参照してください。
Debug Colorで色替えしたら分かりやすいかも。
頭の上に平らになるようにするとリフティングしやすいです。

ヘディングのスクリプト
ヘディング力の数値を設定
・SPEEDやJUMP_VELOCITYの下に「HEAD_FORCE」という押す力を数値設定
const HEAD_FORCE = 200.0
ジャンプでヘディング当たりを発生
・空中にいる時に当たりを発生
・func _processの中に以下のスクリプトを追加
if not is_on_floor():
$HeadArea.set_monitoring(true) # 空中なら攻撃範囲を有効にする
else:
$HeadArea.set_monitoring(false) # フロアの上なら攻撃範囲を無効
HeadAreaのシグナルを受信
・PushAreaと同様にKickerスクリプトへシグナルを接続
・Kickerスクリプトの最後尾にfunc _on_head_body_enteredを確認
・pass以降を以下のコードに変更
func _on_head_area_body_entered(body: Node2D) -> void:
if body is RigidBody2D and velocity.y != 0:
print("頭がヒット")
body.apply_impulse(Vector2(0, HEAD_FORCE)) # 例: 相手に衝撃を与える
ヘディング
ボールの真下に入り込んでジャンプするのが難しいですができました。

当たり判定をチェック
デバッグ機能「コリジョン形状の表示」
ちなみに、デバッグの「コリジョン形状を表示」でコリジョンを見れます


次は攻撃を作ります!
誰かのお役に立てれば幸いです。