UnityでARブロック崩し的なやつを作ろうとしたら、下のgifのようにボールが壁にあたっても全く跳ね返らない。「Unity ブロック崩し」で検索して出てきた通りにPhysics Material等を設定しても一向にだめ。
#結論
UnityにおけるオブジェクトのScaleはm単位なので、ARで現実空間に表示する際はScaleを小さい値に設定することが多い。今回もUnity上でオブジェクトのScaleを0.05(5cm)とかに設定し、それに合わせてボールの速度も0.15(15cm/s)に設定していた。ところが、Unityには処理のオーバーヘッドを減らすために速度の遅すぎるオブジェクトの物理演算ををカットする設定があるらしく、今回は跳ね返りに関するBounce Thresholdに引っかかっていた(参考:Unityマニュアル)。
Bounce Threshold
速度の値を設定します。 2つの衝突するオブジェクトの相対速度がこの値より小さい場合、オブジェクトは互いに跳ね返りません。この値はジッタも減少させるため、非常に低い値に設定することは推奨されません。
デフォルトではBounce Thresholdが0.2になっており、ボールの速度0.15がちょうど閾値を下回っていたため跳ね返らなくなっていた。
#解決策
UnityメニューのEdit->Project Settings->Physicsを開き、Bounce Thresholdの値を小さくする。今回はボールの速度が0.15なのでそれより小さい0.1に設定した。
結果、下のgifのように見事宇宙飛行士が宙を舞うようになった。
#余談
Bounce Thresholdの他にSleep Thresholdという値もある。
Sleep Threshold
キネマティックでないリジッドボディがスリープ状態になる可能性があるグローバルエネルギーの閾値を設定します。リジッドボディがスリープ状態のときはフレーム毎に更新されるわけではないため、リソースの負担は少なくなります。 リジッドボディの運動エネルギーを質量で割った値がこの閾値を下回る場合、スリープの候補となります。
運動エネルギーを参照するため、速度を更に遅くしたり質量を下げたりすると引っかかる可能性がある。
#環境
- macOS Big Sur
- Unity2019.4.28f1
- AR Foundation 3.1.0