UnityのOnCollisionEnterで表面の法線が得られないのはなぜですか?それらを取得する最も信頼できる方法は何ですか?


11

Unityのonコリジョンイベントは、発生したコリジョンに関するいくつかの情報を提供するCollisionオブジェクトを提供します(ヒット法線を持つContactPointsのリストを含む)。

しかし、得られないのは、衝突したコライダーの表面法線です。これは説明するためのスクリーンショットです。赤い線はからContactPoint.normal、青い線はからRaycastHit.normalです。

ここに画像の説明を入力してください

これは、簡素化されたAPIを提供する情報を隠すUnityのインスタンスですか?または、標準の3Dリアルタイム衝突検出技術でこの情報が収集されないのですか?

そして質問の2番目の部分について、衝突の表面法線を取得するための確実で比較的効率的な方法は何ですか?

レイキャスティングによって表面の法線が得られることはわかっていますが、これをすべてのシナリオで実現するには、いくつかのレイキャストを行う必要があるようです(接触点と通常の組み合わせで最初のキャストのコライダーが欠落するか、すべての平均を行う必要があるかもしれません)最良の結果を得るための接触点の法線)。

私の現在の方法:

  1. Collision.contacts[0].point通常のヒットに沿ってバックアップします

  2. 否定ヒットダウンレイキャスト通常のためfloat.MaxValueに、Collision.collider

  3. それが失敗した場合、通常の否定されていない状態でステップ1と2を繰り返します。

  4. それが失敗する場合は、ステップ1〜3を試してください。 Collision.contacts[1]

  5. 成功するまで、またはすべての接点がなくなるまで4を繰り返します。

  6. あきらめて、戻りVector3.zeroます。

これはすべてをキャッチしているようですが、これらすべてのレイキャストは私をうるさくします、そしてこれが十分なケースで機能することをテストする方法がわかりません。もっと良い方法はありますか?

編集 これが本当に3Dコリジョンでの方法である場合、一般的な場合の理由の概要は、Unityに固有の何かと同様に歓迎されます。


これは単なる好奇心のためですか、それとも何かしようとして行き詰まっていますか?つまり、なぜ表面法線が必要だと思いますか?不特定の問題の解決策を「修正」する方法ではなく、達成しようとしている効果について質問してください。誰かが解決を手助けできるかもしれません。:)
Sean Middleditch、2012年

@SeanMiddleditch同意しません。質問はよく書かれていて、それはまさに私が探していたものでした。この質問とその回答は、私が間違っていた問題を修正するのに役立ちました。
SteakOverflow

回答:


12

これは、実際に衝突が発生する方法です。3Dだけでなく2Dも。次の例を見てください。

重複するAABB

緑と赤のAABBが衝突し、接触マニホールドは青い領域です。接点は青い領域のどこかにあります(正確には、アルゴリズムによって異なる可能性がありますが、青/赤/緑が交わる角は理想的です)。

どのサーフェス法線を返す必要がありますか?赤いAABBの上端または左端?緑色のボックスが落ちている場合は、おそらく上端を合理的に推測できます。右に動いている場合は、おそらく左端を合理的に推測できます。それが下降していて正しい場合はどうなりますか?最小浸透の軸をとっていますか?最高速度の速度軸?両方のヒューリスティックですか?ボックスがコーナーで正確に衝突した場合はどうなりますか?

これを、数百のトライ/面で構成される可能性のある複雑な3Dサーフェスに拡張します。あなたはまだ少数の理想的な感じの接触点を持つことになります。どのサーフェス法線を返す必要がありますか?トライメッシュ全体の平均表面法線(ほとんどのオブジェクトでは意味がありません)?衝突するボックスのコーナーの直下にあるポイント(他のほとんどの形状では明確に定義されていません)?生成された接触点に最も近い面を見つけようとしますか(接触点はメッシュ面から直接計算されないため、2回目のパスが必要になります)?最も近い面が見つかった場合、面の法線を使用するか、または接触点で面の頂点を補間して「滑らかな」オブジェクトの正しい法線を取得しますか?

本当に、主な問題は、接触点がすべての接触点ではないということです。結局のところ、多くの場合、それは無限のポイントのセットになります。それらはよく分散されたいくつかのポイントであり、これらのポイントに力を加えて衝突するオブジェクトを反逆的な方法で押し付けることにより、物理的反応を概算することを合理的に実現可能にします。実際のオブジェクト接触の特定のポイント/場所は、単純化された数学モデルの背後に抽象化されています。したがって、接触の特定の表面法線のアイデアは、一般的なケースではあまり意味がありません。

もちろん、オブジェクト、ワールド、モーションに対するより具体的な制約と制限があれば、サーフェス法線について通知できる別の衝突アルゴリズムを作成できます。上記の2Dの場合、ボックスが回転しないと仮定し、ボックスの相対速度と最後の位置がわかっている場合は、連続衝突検出を使用して、いつ衝突するか、どのフィーチャが衝突するかを正確に調べて、衝突が発生した正確なフィーチャ。これは、接触/衝突/サーフェス法線として使用できます。プラットフォーマーゲームは完全にそのような仮定と特別なトリックに基づいて構築されています(これが、Box2DやHavokなどの一般的な物理ライブラリまたはライトを使用しても、マリオやソニックなどの古典的なプラットフォーマーで見られるようなタイトで正確なコントロールが生成されない理由です。言いたい」

Unity3Dで使用されるような一般的なニュートン物理学ライブラリは、そのような単純化と仮定を行うことはできません。そのため、衝突面の法線は得られず、一般に接触点まで簡略化された接触多様体が得られます。


これは素晴らしい答えです。まさに私が探していたものに感謝します。特定の問題は、衝突時にキネマティックリジッドボディに説得力のある反射ベクトルを取得することでした。この種の情報でレイキャストするか、3つの接点(利用可能な場合)を取得してクロス積を取得するかを選択する場合の通常のアプローチはありますか?
michael.bartnett 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.