推測航法では、運動学的状態と呼ばれる変数のグループが機能する必要があります。通常、特定のオブジェクトの位置、速度、加速度、向き、および角速度が含まれます。位置のみを探している場合は、方向と角速度を無視することを選択できます。位置だけでなく方向も予測したい場合は、コメントを投稿してください。回答を更新します。
ネットワーク ゲームの標準的な推測航法アルゴリズムを次に示します。

上記の変数は次のように記述されます。
P t : 推定位置。出力
P O : オブジェクトの最新の位置更新
V O : オブジェクトの最新の速度更新
A O : オブジェクトの最新の加速度更新
T: 現在時刻と最後の更新のタイムスタンプとの間の経過秒数。パケットが受信された時刻ではありません。
これを使用して、サーバーから更新を受信するまでオブジェクトを移動できます。次に、推定された位置 (上記のアルゴリズムの最新の出力) と、受信したばかりの実際の位置の 2 つの運動学的状態があります。これら 2 つの状態を現実的にブレンドするのは難しい場合があります。
1 つのアプローチは、古い方向を将来に投影しながら、2 つの状態の間に線を作成することです。ベジエ スプライン、 Catmull-Rom スプライン、エルミート曲線(他の方法のリストはこちら) などの曲線を作成することをお勧めします。したがって、新しい状態を取得するまで、古い状態を使用し続けてください。つまり、あなたが溶け込んでいる状態が古い状態になるときです。
もう 1 つの手法は、射影速度ブレンドを使用することです。これは、2 つの射影 (最後の既知の状態と現在の状態) のブレンドであり、現在レンダリングされた位置は、特定の時間における最後の既知の速度と現在の速度のブレンドです。
「Game Engine Gems 2」という本を引用しているこの Web ページは、推測航法の宝庫です。
ネットワーク化されたゲームのための信頼できる推測航法
編集:上記のすべては、更新を取得しない場合にクライアントがどのように動作するかを示しています。「サーバーからクライアントにメッセージを送信するタイミング」に関して、Valve は、優れたサーバーは約 15 ミリ秒間隔 (1 秒あたり約 66.6 ミリ秒) で更新を送信する必要があると述べています。
注: 「Valveが言う」リンクには、ソース マルチプレイヤー ネットワークを媒体として使用した、ネットワークに関する優れたヒントも記載されています。時間があればチェックしてみてください。
編集 2 (コードの更新!):
C++/DirectX 環境でこのようなアルゴリズムを実装する方法を次に示します。
struct kinematicState
{
D3DXVECTOR3 position;
D3DXVECTOR3 velocity;
D3DXVECTOR3 acceleration;
};
void PredictPosition(kinematicState *old, kinematicState *prediction, float elapsedSeconds)
{
prediction->position = old->position + (old->velocity * elapsedSeconds) + (0.5 * old->acceleration * (elapsedSeconds * elapsedSeconds));`
}
kinematicState *BlendKinematicStateLinear(kinematicState *olStated, kinematicState *newState, float percentageToNew)
{
//Explanation of percentateToNew:
//A value of 0.0 will return the exact same state as "oldState",
//A value of 1.0 will return the exact same state as "newState",
//A value of 0.5 will return a state with data exactly in the middle of that of "old" and "new".
//Its value should never be outside of [0, 1].
kinematicState *final = new kinematicState();
//Many other interpolation algorithms would create a smoother blend,
//But this is just a linear interpolation to keep it simple.
//Implementation of a different algorithm should be straightforward.
//I suggest starting with Catmull-Rom splines.
float percentageToOld = 1.0 - percentageToNew;
final->position = (percentageToOld * oldState->position) + (percentageToNew * new-State>position);
final->velocity = (percentageToOld * oldState->velocity) + (percentageToNew * newState->velocity);
final->acceleration = (percentageToOld * oldState->acceleration) + (percentageToNew * newState->acceleration);
return final;
}
幸運を祈ります。ゲームで何百万ドルも稼いだら、私をクレジットに入れてみてください ;)