XNAでリドグレンを試していますが、「ラグ」に問題があります。
私は彼らのXNAサンプルをダウンロードしましたが、彼らのサンプルでさえ遅れていることに気づきました。問題は、反対側の動きがスムーズではないということです。私はこれをインターネットではなくLAN(実際には同じコンピューター上)で試しています。
リドグレンとXNAとの接続が遅れているために、スムーズでない動きに関して同じ問題が発生したことはありますか?
リンクしたサンプルは、ネットワークから受け取るものに直接位置を設定します。これはマルチプレイヤーゲームにはお勧めできません。
実際のゲームで行うべきことは、ローカル位置とリモート位置の間を補間することです。したがって、receiveメソッドは次のようになります。
void Receive(packet)
{
unit.RemoteX = packet.Read_X_Position();
unit.RemoteY = packet.Read_Y_Position();
}
これはユニットのローカル位置には影響しません。代わりに、更新メソッド(フレームごと)で、ローカル位置をリモート位置に移動します。
void Interpolate(deltaTime)
{
difference = unit.RemoteX - unit.LocalX
if (Math.Abs(difference) < threshold)
unit.LocalX = unit.RemoteX
else
unit.LocalX += difference * deltaTime * interpolation_constant
}
次に、ユニットの「ローカル」位置を表示します。これにより、次のようなラグのない動きが実現します。
本来あるべき位置に向かってスムーズに動くので、ラグが全くないように見えます!
補間定数は、ローカル位置とリモート位置が収束する速度を制御します。
これらのオプションの間のどこかで妥協点を選択する必要があります。
この種のシステムを実装する際には、他にも考慮すべきことがいくつかあります。たとえば、ユニットがリモート位置からどれだけ離れているかについて上限が必要になることがよくあります。そうしないと、状況によってはローカル状態とリモート状態が「スタック解除」される可能性があります。それらが離れすぎている場合(極端なラグの場合を除いて決して起こらないはずです)、ゲームを停止してユーザーにラグが大きすぎることを伝えるか、ユニットをまっすぐに所定の位置にジャンプします。これはラグに見えますが、少なくともゲームは継続する。
補遺:この回答を読み直すと、時間差を追跡することが強化されると思います。システムのラグが(大まかに)わかっている場合は、リモート位置にあるパケットを受信すると、そのパケットが過去にどれだけ離れているかが大まかにわかります。リモート速度も送信する場合は、オブジェクトが現在どこにあるかを予測できます(一定の速度を想定)。これにより、一部のゲームでは推定ローカル状態と実際のリモート状態の差が小さくなる可能性がありますが、他のゲーム(速度の変化が多い)では状況が悪化する可能性があります。
私はマルチプレイヤーfpsゲームの作成を検討してきました。まず、いくつかの立方体を動かして、観客モードにある別のマシンで位置/回転を複製するデモから始めました。
上記のコードサンプルを使用していますが、うまく機能しています(スムーズに見えるように、補間定数を1より大きく調整する必要がありました)。
現在の時刻と受信したメッセージのタイムスタンプとの時間差を考慮した補間の例をいくつか見てきました。
このコードは時間差を使用していないので、補間は必要なだけ、目標値に到達するまで(または、少なくともしきい値内で所定の位置にスナップするまで)かかります。私の質問は、これに何か利点はありますか?
どうもありがとう。