Version: 2022.3
言語: 日本語
衝突
CCD (連続的衝突判定)

衝突の基本

Unity はゲームオブジェクト同士の衝突をコライダーで処理します。コライダーはゲームオブジェクトに取り付けられ、物理演算に基づく衝突を適用する際のゲームオブジェクトの形状を定義します。コライダーは不可視で、ゲームオブジェクトのメッシュと全く同じ形である必要はありません。メッシュの大まかな近似の方が、ゲームでは効率的で見分けがつかない場合があります。

単純な (プロセッサー負荷の小さい) コライダーを プリミティブ なタイプのコライダーと呼びます。3D には、Box ColliderSphere ColliderCapsule Collider があります。2D では、2D BoxCollider2D CircleCollider を使う事ができます。1 つのゲームオブジェクトに対してこれらのコライダーを何個でも加えて、複合コライダー を作成できます。

複合コライダー

複合コライダーは、プロセッサーのオーバーヘッドを低くおさえつつ、ゲームオブジェクトの形状をうまく近似することができます。さらに自由度を上げるためには、子ゲームオブジェクトにコライダーを追加します。例えば、親ゲームオブジェクトのローカル座標に相対的に、ボックスを回転させることができます。このような複合コライダーを作成する場合は、階層のルートオブジェクトに設定する Rigidbody コンポーネントは 1 つだけにするべきです。

プリミティブコライダーは、シアートランスフォームでは正しく機能しません。トランスフォーム階層で回転と不均一なスケールの組み合わせを使用して、結果の形状がプリミティブ形状ではなくなった場合、プリミティブコライダーはそれを正しく表現できません。

メッシュコライダー

ただし、複合コライダーでさえ十分に正確でない場合があります。3D では、Mesh Colliders (メッシュコライダー) を使用すると、ゲームオブジェクトのメッシュの形状に正確に一致させることができます。2D では、Polygon Collider 2D (2D ポリゴンコライダー) はスプライトグラフィックスの形状と完全には一致しませんが、形状を任意の LOD に調整できます。

これらのコライダーはプリミティブタイプよりもはるかにプロセッサーに負荷をかけるため、良好なパフォーマンスを維持するために慎重に使用してください。また、メッシュコライダーを別のメッシュコライダーと衝突させることはできません (つまり、接触させても何も起こりません)。Inspector でメッシュコライダーの Convex (凸状にする) にチェックすることで、これを回避できる場合があります。これにより、コライダーの形状を “凸包” に生成します。これは、元のメッシュに似ていますが、くぼみが埋められています。

この利点は、凸状メッシュコライダーは他のメッシュコライダーと衝突可能であるため、適切な形状の動くキャラクターにこの機能を使用できることです。ただし、推奨する使用法は、シーンのジオメトリにメッシュコライダーを使用し、移動するゲームオブジェクトの形状を複合プリミティブコライダーを使用して近似することです。

静的コライダー

Rigidbody (リジッドボディ) コンポーネントなしでコライダーをゲームオブジェクトに加え、シーンの床、壁、その他の静止要素を作成できます。これらは 静的 コライダーと呼ばれます。反対に、リジッドボディを持つゲームオブジェクトのコライダーは、 動的 コライダーと呼ばれます。 静的コライダーは動的コライダーと相互作用しますが、リジッドボディがないため、衝突に反応して移動することはありません。

物理マテリアル

コライダーが相互作用する時、それらの表面ではマテリアルの特性をシミュレートする必要があります。例えば、氷上では滑りやすく、ゴムボールは摩擦力が大きく非常に跳ねやすい、というように。衝突中にコライダーの形状は変化しませんが、摩擦や弾力を Physics Materials (物理マテリアル) を使用して設定することが可能です。パラメーターをちょうど良い値にするには、若干の試行錯誤が必要になります。例えば、氷のようなマテリアルの摩擦は 0 (または、とても低い値) ですし、ゴムのようなマテリアルは強い摩擦を持ち、ほぼ完全な弾性を持っています。使用可能なパラメーターについての詳細は Physic MaterialPhysics Material 2D を参照してください。慣習によって、Physic Material の Phisic には s が付いていませんが、Physics Material 2D には s が付いています。

トリガー

スクリプトのシステムで衝突を検出し OnCollisionEnter 関数を使用してアクションを開始する事ができます。衝突させるのではなく、あるコライダーが他のコライダーの領域に侵入したことを検出したい場合は、物理エンジンを使えば簡単に検出可能です。コライダーを Trigger ( Is Trigger プロパティを使用します) に設定すると、固体オブジェクトとしては動作しなくなり、他のコライダーがすり抜け可能になります。任意のコライダーがトリガーに設定されたコライダーの領域に侵入すると、トリガーはトリガーオブジェクトのスクリプトにある OnTriggerEnter 関数を呼び出します。

スクリプトの衝突コールバック

衝突が発生したとき物理エンジンはオブジェクトにアタッチされたスクリプトにある特定の関数を呼び出します。衝突イベントに対応するため数ある関数の中から好きなものをコードとして配置することができます。例えば車が障害物にぶつかったときにクラッシュ音を鳴らすというようにです。

衝突が検出された時の最初の物理演算の更新で OnCollisionEnter 関数が呼び出されます。コライダー同士の接触が維持されている間の更新では OnCollisionStay 関数が呼び出され、最終的に、OnCollisionExit 関数がコライダー同士の接触が終わったことを示します。トリガーのコライダーでは類似した OnTriggerEnterOnTriggerStayOnTriggerExit 関数を飛び出します。2D 物理演算では、例えば OnCollisionEnter2D というように、関数名に 2D が加えられた同等の関数が存在します。これらの関数の詳細とサンプルコードはスクリプトリファレンスの MonoBehaviour を参照してください。

通常、非トリガー同士の衝突では、最低 1 つのオブジェクトはキネマティックでない Rigidbody (つまり Is Kinematic がオフ) でなければいけない制限があります。もし両方のオブジェクトがキネマティックの Rigidbody である場合 OnCollisionEnter その他は呼び出されません。トリガー同士の衝突ではこの制限は適用されず、Rigidbody がキネマティックでもそうでなくても、トリガーコライダーに侵入したときに OnTriggerEnter が呼び出されます。

コライダーの相互作用

コライダーは Rigidbody の設定次第で異なった相互作用をします。3 つの重要な設定は Static Collider (Rigidbody がまったくアタッチされていない)、Rigidbody ColliderKinematic Rigidbody Collider です。

静的コライダー

静的コライダーはコライダーを持ち、Rigidbody を持たないゲームオブジェクトのことを指します。静的コライダーは、大抵レベルのような、常に同じ場所に留まり、動きまわることが無いジオメトリに使用します。Rigidbody オブジェクトは静的コライダーと衝突しますが、静的コライダーを移動させることはできません。

特定のケースでは、物理エンジンは決して動かない静的コライダーを最適化します。例えば、静的コライダーの上に載っている車両は、この静的コライダーを動かしてもスリープ状態のままです。物理エンジンの計算速度に特別な影響を与えることなく、実行時に静的コライダーを有効化、無効化、または移動できます。また、スケールが均一である (傾斜していない) 限り、静的メッシュコライダーを安全にスケーリングできます。

Rigidbody コライダー

これはコライダーと通常の、キネマティックでない Rigidbody をアタッチしたゲームオブジェクトです。Rigidbody コライダーは物理演算エンジンによって完全にシミュレートされ、スクリプトから適用される衝突や力に反応することができます。それらは他のオブジェクト (静的コライダーも含む) と衝突が可能で、物理エンジンを使用するゲームではもっともよく使用されるコライダーの設定になります。

キネマティックな Rigidbody コライダー

これは、コライダーとキネマティック Rigidbody (Rigidbody の IsKinematic プロパティを有効にしたもの) をアタッチしたゲームオブジェクトです。Transform コンポーネントの変更によってスクリプトから キネマティック Rigidbody オブジェクトを動かすことが可能ですが、キネマティックでない Rigidbody のように衝突や力を加えて動かすことはできません。キネマティック Rigidbody はたまに動かしたり、無効/有効にするコライダーのために使用しますが、それ以外は静的コライダーのような動作をします。例の 1 つとして、通常、固定された物理的な障害物であるスライドドアですが、必要に応じてドアが開きます。静的コライダーとは異なり、他のオブジェクトと接触するとき、動くキネマティック Rigidbody によって他のオブジェクトに摩擦が生じ、他の Rigidbody が呼び起こされます。

移動しない場合でも、キネマティック Rigidbody は静的コライダーとは異なる動作をします。例えばコライダーにトリガーが設定されているとき、スクリプト内でトリガーイベントを受信するためには Rigidbody を追加する必要があります。トリガーを重力の影響で落下させたくないときや物理エンジンの影響を受けさせたくない場合は Rigidbody の IsKinematic にチェックを入れます。

Rigidbody コンポーネントの動作は IsKinematic プロパティを使う事で、いつでも通常の状態とキネマティックを切り替える事ができます。

切り替えの一般的な例としては、通常アニメーションにしたがって動くキャラクターが、爆発や激しい衝突などによって物理的に放り出されたときの「ラグドール」効果があります。キャラクターの手足にはそれぞれ、デフォルトで IsKinematic が有効な Rigidbody コンポーネントがあります。手足は普段、アニメーションにしたがって動きますが、それらすべての IsKinematic がオフになると、即座に物理演算オブジェクトのように動作します。すると、衝突や爆発のときに自然な手足の動きでキャラクターを吹き飛ばすことができます。

衝突アクションマトリックス

2 つのオブジェクトが衝突するとき、さまざまなスクリプトイベントは衝突するオブジェクトの Rigidbody の設定に応じて発生します。下の表は、どのイベント関数が呼び出されるかをオブジェクトにアタッチされているコンポーネントに基づいて詳細にまとめたものです。組み合わせのいくつかは 2 つのオブジェクトのうち片方にしか影響しませんが、一般的なルールとして物理演算は Rigidbody コンポーネントがアタッチされていないオブジェクトには適用されません。

衝突時に衝突検出が起こり、メッセージが送信されます
静的コライダー Rigidbody コライダー キネマティック Rigidbody コライダー 静的 トリガーコライダー Rigidbody トリガーコライダー キネマティック Rigidbody トリガーコライダー
静的コライダー   サポート        
Rigidbody コライダー サポート サポート サポート      
キネマティック Rigidbody コライダー   サポート        
静的 トリガーコライダー            
Rigidbody トリガーコライダー            
キネマティック Rigidbody トリガーコライダー            
トリガーメッセージが衝突時に送信されます
静的コライダー Rigidbody コライダー キネマティック Rigidbody コライダー 静的 トリガーコライダー Rigidbody トリガーコライダー キネマティック Rigidbody トリガーコライダー
静的コライダー         サポート サポート
Rigidbody コライダー       サポート サポート サポート
キネマティック Rigidbody コライダー       サポート サポート サポート
静的 トリガーコライダー   サポート サポート   サポート サポート
Rigidbody トリガーコライダー サポート サポート サポート サポート サポート サポート
キネマティック Rigidbody トリガーコライダー サポート サポート サポート サポート サポート サポート
衝突
CCD (連続的衝突判定)