Unityでゲームを作っていて、物体同士の接触を検出したい、となったので
いろいろ調べて試行錯誤した結果をまとめてみる。
検出したい衝突は、
1.プレイヤーが放り投げたボールが地面(Terrain)に着地するとき
2.動的に生成されるブロックに敵キャラクターが接触したとき
#ColliderとRigidBodyの組み合わせ
物体同士の衝突を検出するには、ColliderとRigidBodyを組み合わせて使う。
用途に応じて最適な組み合わせを選ぶ必要があるらしい。
Unity公式マニュアルでは3種類の組み合わせが紹介されている。
ざっと特徴をまとめると、
###静的コライダー
RigidBodyは持たず、Colliderのみを持つゲームオブジェクト。
壁など動きがないオブジェクトに適用することが前提。
このゲームオブジェクトをゲーム中に移動したり、
有効・無効を切り替えるとパフォーマンスが低下する。
###RigidBodyコライダー
ColliderとRigidBodyを持ち、RigidBodyのisKinematicをオフにしたゲームオブジェクト。
物理演算によるシミュレートと衝突判定が必要な場合に最適。
###KinematicRigidBodyコライダー
ColliderとRigidBodyを持ち、RigidBodyのisKinematicをオンにしたゲームオブジェクト。
時々動かしたり有効・無効の切り替えが必要なオブジェクトに最適。
「1.プレイヤーが放り投げたボールが地面(Terrain)に着地するとき」の場合、
ボールは物理演算が必要なのでRigidBodyコライダーに、
地面は静的コライダーとしてTerrainColliderをアタッチしてうまくいった。
「2.動的に生成されるブロックに敵キャラクターが接触したとき」では、
Instantiateで生成するブロックのプレハブはゲーム中位置が動かず、
有効無効を切り替えたいのでKinematicRigidBodyコライダー。
敵キャラクターはCharacterControllerをつけてみたがうまく衝突が検出されない。
いろいろ試行錯誤した結果、
ブロックプレハブはKinematicRigidBodyコライダーでIsTriggerをオンにし、
OnTriggerEnter()で衝突を検出。
敵キャラはCharacterControllerとRigidBodyをつけ、
プレハブから複製されるブロックの名称末尾の「ブロック名(Clone)」の
(Clone)を削除することでうまくいった。
プレハブから生成されたオブジェクトはデフォルトで「プレハブ名(Clone)」となるが、
この(Clone)があるとなぜかうまく衝突が検出されなかった。