OnTriggerStay2Dとは
トリガー状態のオブジェクトのコライダーと別のオブジェクトのコライダー衝突している間、毎フレーム呼び出され続けます。(2D 物理挙動のみ) 入ったオブジェクトに関する詳細な情報は呼び出し時に渡される Collision2D 引数に代入されます。
Unity公式サイト
つまり、Collider同士が接触している間に、毎フレーム呼ばれ続ける(はず)ですよね。
少なくとも私はそう思っていました。
しかし、ある作業をしていて偶然プレイヤー(Collider2D)と炎(isTriggerのCollider2D)が接触しつづけているのに、HPは減らないことに気づいた。なんで?
そこで色々調べたらどうも原因は負荷軽減で物理計算を減らすため、動かなくなったオブジェクトはSleep状態へ移行してしまっているためであるらしい。
なるほど、なるほど
解決方法
解決方法はいくつかありますが、実装内容によって最適な方法を選んでやるといいです。
対象のRigidbody2DのSleeping ModeをNever Sleepにする
こちらの方法は一番手っ取り早いでしょうか。これだけで毎フレーム必ず呼ばれ続けます。ただし、負荷ももちろん高いので考えものですね。
Time to Sleepを指定の秒数に変更
こちらはつまり、静止状態になったオブジェクトがSleep状態へ遷移するまでの時間(秒)を設定することができます。デフォルトは0.5秒。それを狙った秒数にすることで、その間は毎フレーム呼ばれ続けます。
Edit -> Project Settings -> Physics2D -> Time to Sleep
Rigidbody2D.WakeUpを呼んであげる
スクリプトで好きなタイミングでWakeUpを呼んであげることで、Sleep状態から目覚めさせることができます。こちらの方法は割と使い勝手がよいのでオススメかもしれないです。
[SerializeField] Rigidbody2D playerRg2d;
void HogeFunction(){
playerRg2d.WakeUp();
}
まとめ
OnTriggerStay2D(OnTriggerStay)は処理負荷を軽減するために、静止状態になったオブジェクトの物理計算周りの処理はSleep状態へ移行してしまう。
それを対処するための方法として
- Rigidbody2DのSleeping ModeをNever Sleepにする
- Edit -> Project Settings -> Physics2D -> Time to Sleepを指定の秒数に変更
- 好きなタイミングでRigidbody2D.WakeUpを呼んであげる
コメント