物理シミュレーションは、物理ワールドで実行されます。各レンダリングに対して 1 つの物理ワールドのみがあり、オブジェクトは同期された状態を保持するためにオブジェクト間でミラーリングされます。
注: Lua でフラグ Application.DISABLE_PHYSICS を Application.new_world() に渡すことで、物理面なしのワールドを作成できます。ワールドが完全に空白である場合でも、各物理ワールドの稼働には著しいコストがかかります(約 0.5 〜 1.0 ms)。このため、ワールドを純粋にグラフィカルな目的(GUI など)で使用している場合は、それらの物理面を無効にしていることを確認します。
物理ワールドには、数多くのアクターまたはリジッド ボディがあります。
アクターは、単一のユニットとして移動する物理オブジェクトです。これは複雑なシェイプを持ち、多くのパーツで構成されている場合がありますが、パーツは常に互いに対して同じ位置にとどまります。たとえば、彫像は常に全体として移動するため、1 つのアクターです。その腕を個別に再配置することはできません。
「物理アクターを作成する」を参照してください。
1 つのラグドールは、その腕と脚が相互にツイストおよびベンドできるようにする必要があるため、複数のアクターで構成されます。したがって、ラグドールには、独立して移動することが可能な各パーツに対して個別のアクターが必要です。
アクターには、1 つまたは複数の衝突シェイプがあります。衝突シェイプは、アクターが他のアクターとどのように衝突するかを決定します。たとえば、ボールが床にぶつかって跳ね返った場合、床の衝突シェイプに接触して跳ね返りを起こすのはボールの衝突シェイプです。
アクターは、静的、キーフレーム設定、または動的の 3 つのモードのいずれかにあります。静的アクターはまったく動きません。キーフレーム設定アクターは、ゲーム ワールドでコントロールされ、その動きが物理ワールドでミラーリングされます(つまり、ゲーム ワールドがマスターとして機能し、物理ワールドがスレーブとして機能します)。アニメーションによってコントロールされるオブジェクトは、通常、キーフレーム設定された物理プロパティを持ちます。動的オブジェクトは物理ワールドによってコントロールされ、ゲーム ワールドにミラーリングされます。
オブジェクトをキーフレーム設定と動的間で変更すると効果的な場合があります。たとえば、あるキャラクタが走り回っているときに、ラグドール アクターをキーフレーム設定にして、キャラクタを追跡させることができます。その後、キャラクタが死んだときに、ラグドール アクターを動的にして、動きをコントロールする物理プロパティを適用します。別のオプションは、キャラクタが死んだときに、ラグドール アクターを作成することです。
キーフレーム設定アクターは、常にアニメートされた動きに従います。動的アクターのパスが衝突に応じて修正されるのに対して、キーフレーム設定アクターはアニメーション パスに沿って移動し続けます。キーフレーム設定アクターは、その衝突イベントを登録しますが、そのパスは自動的には修正されません。キーフレーム設定アクターが動的アクターと衝突すると、動的アクターが常に押しのけられます。キーフレーム設定アクターは、無限の質量を持つ動的アクターであるかのように動作します。
注: オブジェクトが衝突を経験し、実際の物理オブジェクトのように動作するアニメーションを作成したい場合があります。たとえば、閉じるドアをアニメートする際、その閉じようとするドアに無限の力が働き、ドアが完全に閉じないようにする場合などです。あるいは、ドアが閉じる過程においてある程度の力で障害物を押すが、その障害物が重いために動作が停止する場合などです。
これを行うには、同じ動作を実現しても物理システムによって認識される、物理的な力にアニメーションを変換する必要があります。これは小さな問題ではなく、常に明確な解決策があるわけではありません。ドアが押す力はどのくらいなのでしょうか?アニメーションが途中で中断されたら何が起こるのでしょうか?
このエンジンは、このような種類の変換はサポートしていません。物理的なアニメーションを実現するには、スクリプトからオブジェクトに手動で力を適用する必要があります。
各物理アクターには、物理シミュレーションでアクターが占めるスペースを表すシェイプがあります。このシェイプは、球体、カプセル、ボックスなどの通常のソリッドにすることも、アクターに関連付けられたメッシュと合わせることも、または Stingray がメッシュから自動的に計算する凸型ボリュームにすることもできます。
静的アクターには、(一般的には)メッシュを使用したモデリングが最適です。これにより衝突テストで最も正確な結果が得られます。
キーフレーム設定アクターは、球体、カプセル、またはボックスとして実行するのが最適です。キーフレーム設定アクターにメッシュを使用することが必要な場合があります。
動的アクターはメッシュをまったく使用できません。球体、カプセル、ボックス、凸型を使用する必要があります。これによりオブジェクトのシェイプに十分な精度が得られない場合は、オブジェクトを複数の小さいアクターに分割できます。たとえば、椅子には、座面と脚をカバーするボックス シェイプのアクターと、椅子の背だけをカバーする別の薄いボックスがある場合があります。
たとえば、ゲームプレイでキーフレーム設定オブジェクトの近くで高精度な射撃がある場合、グラフィカル ジオメトリにできる限り近い衝突を実現するために、メッシュの使用が必要となる場合があります。この場合の最適なオプションは、レイキャスティングのみで使用されるメッシュを作成することです。メッシュは他の物理オブジェクトと衝突しないように設定する必要があります。
スクリプト プログラマは、物理ワールドをプローブするために、レイキャスティングとシェイプのクエリーを使用することができます。レイキャストは、レイが物理ワールドの 1 つのポイントから、物理ワールドの別のポイントに通過することで衝突する物理オブジェクトを検出します。通常、レイキャストは、弾丸が当たるオブジェクトや、プレイヤーが別のプレイヤーを見ることができるかどうかを決定するために使用されます。
シェイプ キャストまたはスイープ テストは、レイキャストに似ていますが、より複雑なシェイプを使用します。シェイプ キャストを使うと、「シェイプ S (たとえば、球体)をポイント A からポイント B に移動すると、A から B へのパスに沿って、球体が何かと最初に衝突するのはどのポイントになるのか?」という疑問を解決できます。
レイキャストまたはシェイプ キャストはいずれも、開始点で既に当たっているオブジェクトとの衝突は検出しません。たとえば、レイが球体の内側から開始した場合は、その球体との衝突はまったく返しません。
シェイプのクエリーは、シェイプを交差するすべての物理オブジェクトを検出します。これは手榴弾の効果などに使用できます(手榴弾の爆発の x m 以内のすべてのアクターを検出して、それらに力を適用します)。
ジョイントまたはコンストレイントは、2 つのオブジェクト間の物理的なリンクです。例として、ラップトップのヒンジを想像してみてください。ヒンジはスクリーンとキーボードを連結していますが、これらは互いに対して回転します。
物理システムは、さまざまな方法でオブジェクトが相互に移動する多様なジョイントをシミュレートすることができます。ヒンジ ジョイントでは、オブジェクトの共通の軸を中心にして回転させることができます。ボール ジョイントとソケット ジョイントでは、1 つのオブジェクトを別のオブジェクトに対して自由に回転させることができます(多様な方向にスピンできる、ソケットに取り付けられたボールなど)。
また、ジョイントは制限と力を使用して設定できます。制限は、ジョイントの回転量を指定します。たとえば、一般的には、ラップトップのヒンジを 180 度まで回転させて完全に平坦になるようにすることはできません。力は、特定の方向にジョイントをプッシュします。これを、たとえば自動開閉装置付きのドアのシミュレーションに使用できます。
ジョイント、制限、および力を使用して、実世界の対応物に似た動作をする複雑なオブジェクトを作成できます。物理システムによって提供される抽象的なジョイントは、実世界のジョイントのすべてのニュアンスをキャプチャしているわけではないため、正確な複製とはなりません。
ラグドールは、手足(前腕、上腕、大腿、すね、頭、胴体)を表すアクターのセットで、死人や意識のない人間の動きを模倣するような方法でアクターを結合するジョイントのセットを使用します。リアルなラグドールの動作を実現するには、多くの微調整が必要です。
「ラグドールを作成して読み込む」を参照してください。
物理システムでは、どのアクターがどの他のアクターと衝突するかを決定するフィルタを設定できます。
通常、パフォーマンスを向上させるためにフィルタを使用します。たとえば、レイキャスティングでのみ使用するアクターがある場合、他のものとは衝突しないように設定することができます。地面に岩や紙くずなどの多数の小さい「破片」ボディがある場合は、これらが他の破片オブジェクトには衝突せず、他の大きなオブジェクトのみに衝突するように設定できます(小さいオブジェクト間の衝突は大きな視覚的な効果がないためです)。
衝突フィルタは、レイキャストとクエリーに対しても使用できます。たとえば、防弾ガラスをシミュレートする場合などに、「弾丸レイ」とは衝突し、「可視性テスト レイ」とは衝突しないようにフィルタを設定できます。
ムーバまたはキャラクタ コントローラを使用して、物理ワールドのキャラクタを表現します。キャラクタは、「実際」の物理オブジェクト(アクター)としてはシミュレートされません。これは実際の物理的オブジェクトには、キャラクタでは不要な多くの動作があるためです。たとえば、キャラクタはバウンス、スライド、転倒することなどができます。
それでも、キャラクタには物理ワールドとの相互作用が必要です。キャラクタが移動するときに、キャラクタがワールド内の他のオブジェクトに貫通しないように、キャラクタの動きを確認する必要があります。
これを解決するために、ムーバを使用します。ムーバはキャラクタを囲むカプセル シェイプです。キャラクタが移動すると、物理ワールドでこのカプセル シェイプが移動して、特殊なアルゴリズムを使用して、物理オブジェクトとの衝突をテストします。このアルゴリズムにより、ゲーム キャラクタの予測される動作として、ムーバをサーフェスに対してスライドさせることができます。
キャラクタが身をかがめると、ゲームでは小さいムーバに切り替えることができ、大きいムーバではアクセスできない領域に入ることを可能にします。
キャラクタのあらゆるパーツが、ゲーム ワールドに貫通するのを防止するには、キャラクタのすべてのパーツがムーバ シェイプの内側にとどまる必要があります(ムーバ シェイプのみがワールドに対する衝突に対してチェックされるため)。
多くの場合、これが問題になります。キックや剣を使用した攻撃などの興味深いアニメーションには、多くのスペースが必要になります。これらを収めるには、かなり大きなムーバが必要となります。しかし、ムーバを大きくすると狭い領域に侵入できなくなり、プレイヤーに不自然な感じを与えるため、問題があります。この問題には完璧な解決策はありません。最適なバランスを見つけるのは、ゲームプレイ コード次第です。一部の貫通が許容できる場合もあります。その他の場合には、キャラクタが壁に近すぎる位置に立っていると壁から押し出される可能性があったとしても、大きな移動の前にムーバを拡大させる方が良い場合もあります。
ベクトル フィールドは、空間内の各ポイントに Vector3 を割り当てる関数です(実際には Vector4 ですが、通常は最初の 3 つの成分のみに関心があります)。
ベクトル フィールドは、空間内のさまざまなポイントにベクトル値を持つあらゆるものを表すのに使用できます。最も一般的な例は、風と水の速度を表すためにベクトル フィールドを使用することですが、磁気や重力などその他の項目に対しても使用できます。風を表現するためにベクトル フィールドを使用している場合、そのベクトル フィールドは空間内の各ポイントにおける風の速度を示します。
ベクトル フィールドは、それに与える効果を再生することで作成されます。効果は、爆発、つむじ風、換気口から上昇気流など、風の速度に影響を与える多様なものを表現するために作成できます。
ベクトル フィールドの風は、物理およびパーティクルの両方に適用できます。
詳細については、「ベクトル フィールド(風)のエフェクトを設定する」を参照してください。
車両はユニットの一部であり、そのユニット内の物理アクターに基づいています。この物理アクターは、車両の寿命期間を通じて車両に必要であり、常に破壊されていない状態であるべきです。車両のベース アクターには、シャーシ(ボディ)とホイールを形成する複数のシェイプが含まれる必要があります。シャーシには 1 つの衝突シェイプが必要で、各ホイールには追加の衝突シェイプが必要になります。それぞれの車両シェイプは、最終的に凸型メッシュである必要があります。凸型メッシュを作成するか、またはエンジンで凸面以外のシェイプに基づいて凸型メッシュを計算します。
「車輪付き」と「タンク」という、2 つの基本タイプの車両がサポートされています。車輪付き車両とタンク車両の間の根本的な違いは、ボディの同じ側のタンク ホイールがすべて同じ速度で動作することです。車輪付き車両ホイールは、独立して動作します。タンク ホイールは、車輪付き車両のように回転して向きを変えません。タンクは各トレッドに異なるレベルのスラストを適用することで向きを変えます。
Stingray ではキーフレーム設定車両はサポートされていません。
車両プロパティは、SI 単位に基づいています。距離はメートル単位で測定され、質量はキログラム単位で測定され、時間は秒単位で計測されます。
「車両の物理特性をセットアップする」および「車両の物理プロパティ」を参照してください。