この記事では RigidBody2D で衝突の「検知」をする方法について書きます。
目次
RigidBody2Dで衝突の検知をする方法
デフォルト状態では衝突検知はできない
RigidBody2Dはデフォルトでは衝突検知はできないようになっています。(正確にはget_colliding_bodies()あたりの関数で検知できるようですけれども未調査)。
おそらくですが、衝突検知の処理は重たいためデフォルトは無効になっているものと思われます。
RigidBody2Dの衝突検知を有効にする方法
Contact Monitor
を有効にすると、RigidBody2Dでも body_entered
シグナルを受け取れるようになります。
方法は、インスペクタから以下のように設定します。
- Contact Monitor: オンにする
- Max Contacts Reported: 1以上の値にする。今回は「8」としました
後は body_entered シグナルを接続します。
衝突を行う RigidBody2Dはスクリプトを以下のように記述しました。
extends RigidBody2D
# -----------------------------------------------
# フルーツオブジェクト.
# -----------------------------------------------
class_name Fruit
# -----------------------------------------------
# const.
# -----------------------------------------------
const TIMER_HIT = 0.5 # ヒット時の点滅時間.
# -----------------------------------------------
# onready.
# -----------------------------------------------
@onready var _spr = $Sprite
# -----------------------------------------------
# var.
# -----------------------------------------------
var _hit_timer = 0.0 # 衝突タイマー.
# -----------------------------------------------
# private functions.
# -----------------------------------------------
## 開始.
func _ready() -> void:
pass
## 更新.
func _physics_process(delta: float) -> void:
_spr.modulate = Color.WHITE
if _hit_timer > 0:
# ヒット点滅.
var rate = 1 - (_hit_timer / TIMER_HIT)
_hit_timer -= delta
var color = Color.RED
_spr.modulate = color.lerp(Color.WHITE, rate)
# -----------------------------------------------
# signal.
# -----------------------------------------------
## 他の剛体と衝突した.
func _on_body_entered(body: Node) -> void:
if body is Fruit:
# フルーツとヒットした.
_hit_timer = TIMER_HIT
今回は壁との衝突を判定したくないため、”Fruit” クラスのみ有効としています。
これで衝突したタイミングで赤点滅する処理が実装できました。
完成プロジェクト
今回のサンプルを実装したプロジェクトファイルは以下からダウンロードできます。