弾丸と敵、またはプレイヤーと床を考えてください。これらのオブジェクトが相互作用する場合、相互作用コードを保持するものは何ですか?
弾丸と敵、またはプレイヤーと床を考えてください。これらのオブジェクトが相互作用する場合、相互作用コードを保持するものは何ですか?
回答:
TL; DR:
あなたのゲームオブジェクトはお互いを知りませんし、他のオブジェクトに対するチェックも実行しません。ゲームオブジェクトをチェックし、適切なアクションを実行してゲームの物理をシミュレートする衝突検出および衝突解決パターンを作成します。
良いもの
衝突検出を記述し、この本を読むという以前の試みから、衝突検出と衝突解決には2つの段階があります。最初の段階(衝突検出)は、2つのオブジェクトに潜在的な衝突があるかどうかを判断するアーリーアウトパスです。2つのオブジェクトが潜在的な衝突を形成する場合、これらのオブジェクトを2番目の段階(衝突解決)に渡し、オブジェクトに対してより詳細なチェックを実行し、衝突の解決を試みます。
エンジン/ゲームのどこかに、あなたの世界のすべてのオブジェクトの配列を保持します。各フレームで、配列をループし、単純なバウンディングボックス/球体衝突検出を使用して、他のすべてのオブジェクトに対して各オブジェクトをチェックします。
擬似コード:
dectectCollisions(objects)
{
for(objectA in objects)
{
for(objectB in objects)
{
if(objectA != objectB) //ignore self
{
if(BoundingSpheresIntersect(objectA, objectB))
{
collisionResolver.addObjects(objectA, objectB);
}
}
}
}
}
この種のループは非効率的ですが、空間的分割を使用して、衝突するには距離が離れすぎていることが保証されているオブジェクトのアーリーアウトとして、改善の余地があります。
2つのオブジェクトの潜在的な衝突をチェックした後(つまり、両方のオブジェクトが衝突するのに十分近い)、オブジェクトはより正確な衝突検出ルーチンを実行するために渡されます。
交差する可能性がありますが、ジオメトリに起因しないランダムな形状とサイズの2つのポリゴンがあるとします。
境界球を使用すると、これらの2つのオブジェクトは潜在的な衝突に対して偽陽性を作成します。ここで、2つのオブジェクトが実際に交差するかどうかを判断するために、より徹底的なパスを実行します。
真の衝突が見つかったら、衝突解決ステップで適切なアクションを実行し、ゲーム物理学の粒度とニーズに応じて力またはモーメントを適用することでオブジェクトを解決します。
これを念頭に置いて、衝突の検出と解決のプロセス全体を抽象化して、オブジェクトがお互いについて何も知る必要がなく、衝突を判断して解決するために必要なプロセスも不要にすることができます。これを処理する2つのクラス/マネージャーは、各オブジェクトの基本的なプロパティを知るだけで、衝突の迅速でダーティなチェックを実行し、必要に応じてより徹底的なチェックを実行できます。
Unreal Engine 3がそれを処理する1つの方法:
弾丸は、何かに当たったことを伝える引数とともに、何かに当たったという衝突メッセージを受け取ります。その後、objectHit.takeDamage(self)を呼び出すことができます。次に、ターゲットは、ヒットしたものへのポインターを含むTakeDamageメッセージを取得し、適切なアクションを実行します。
私はこのアプローチが個人的に好きです。というのは、弾丸は特別なアクションをとることができ(ヒットしたもののタイプに応じて何らかの爆発効果をもたらすなど)、ターゲットは弾丸のタイプに応じて特別なアクションをとることができるからです。
また、弾丸がターゲットに対して何を行うかを知っており、objectHit.freeze(self)のように、その弾丸に対して関数を呼び出すことができます。その後、ターゲットは、フリーズする何かにヒットしたこと、およびどのようなオブジェクトであったかを認識します。
編集:この答えは、おそらくUE3を使用していないため、どのように機能するかの一般的な図を意味します。:)
シーフは、ソースとレセプトロンを備えたダークエンジンでこれを非常にうまくやった。オブジェクトには、これらの両方のプロパティがあり、種類が異なります。たとえば、水の矢印には、接触時にWaterStimのソースがあります。爆発するとAoE FireStimが発生します。
Water Arrowがオブジェクトに当たると、ターゲットオブジェクトは、適切な強度値を持つWaterStimを探しているものをレセプトロンで検索します。次に、それに関連付けられているコマンドを実行します(この場合、燃えるトーチをオフトーチに変え、煙を一気に放出します)。
SystemShock2で同じエンジンが使用されているため、これがすべての異なるダメージタイプの処理方法であり、異なる弾丸は異なる刺激セットを持ち、異なるモンスターは異なる刺激タイプのレセプトロンを持ち、1 *、2 *、1 / 2弾薬の種類が「超効果的」かどうかに依存する強度。
レベルエディタでオブジェクトにソースとレセプトロンを追加できるため、非常に柔軟なシステムのように見えました(たとえば、火事に見舞われた場合に開くワンオフドアを作成するために)。オブジェクトに特別なスクリプトが関連付けられている場合。
したくないことは、考えられるすべてのオブジェクトと衝突する可能性のあるすべてのオブジェクトのnXn相互作用行列をハードコーディングする必要があることです!標準化されたメッセージを通じて相互作用を一般化することにより、プロセスを簡素化します。