Bulletを使用すると、物理がネットワーク上で正しく同期しない


11

Bulletを使用してクライアント/サーバーの物理システムを実装しようとしていますが、同期をとるのに問題があります。

ゲームオブジェクトから変換を読み書きするカスタムモーション状態を実装しましたが、ローカルで動作しますが、ネットワーク化されたゲームに対して2つの異なるアプローチを試しました。

  1. サーバー上にも存在するクライアント上の動的オブジェクト(たとえば、ランダムな破片やその他の重要ではないもの)は運動学的に作成されます。これは正しく動作しますが、オブジェクトは非常にスムーズに移動しません
  2. オブジェクトは両方で動的ですが、オブジェクトが移動したというサーバーからの各メッセージの後に、線形速度と角速度をサーバーからの値に設定し、サーバーのトランスフォームでbtRigidBody :: proceedToTransformを呼び出します。また、btCollisionObject :: activate(true);を呼び出します。オブジェクトを強制的に更新します。

方法2の私の意図は基本的に方法1を行うことでしたが、方法1をスムーズにするために自分で行う代わりにBulletを乗っ取って貧者の予測を行いましたが、これはうまくいかないようです(理由が100%明確ではないため)私は弾丸を踏んでさえいます)そしてオブジェクトは時々異なる場所に行き着きます。

私は正しい方向に向かっていますか?Bulletには独自の補間コードが組み込まれているようです。それは私が方法1をうまく機能させるのに役立ちますか?または、誤って踏みつけているため、方法2のコードが機能していませんか?

編集:私が気付いた方法1のもう1つの問題は、同期されていないオブジェクトに対する衝突の衝突応答が大幅にずれることです。キネティックボディは、ノックバックできないため、時々無限にシュートするものです。


答えを得るのに役立つ可能性があるいくつかのこと:どの言語/エンジンを使用していますか?どのような種類の接続ですか?サーバーへのpingと比較して、同期の不足はどの程度悪いですか?
Fibericon

2
2番目のオプションは機能しません。数フレーム後に速度をサーバー値に設定するだけなので、各パケット間でドリフトする可能性があるフレームがいくつか存在するためです。ゲーム物理学に関するすべてのGafferの投稿を読むことをお勧めします。おそらく最初に「タイムステップを修正する」を読むべきですが、これがネットワーク化物理学について話している最後の記事ですgafferongames.com/game-physics/networked-physics
Roy T.

私はC ++で自己開発したエンジンを使用しています。しかし、私は同期の不足がそれほど悪くないことを確信しています。推測する必要がある場合は、おそらく1フレームのpingを超えていますが、まだほとんどLANのみのテストを行っています。私はそれらの記事をチェックするつもりです、そうです、あなたは速度がずれているのは正しいです。しかし、物事はある方法クレートは、マップ全体にあるように、オフ。トランスフォームを明示的に設定することで、最終的には一般的に準拠すべきではありませんか?(まだきれいではない場合でも、ジグルなど)
Lucas

ガファーの投稿を読んだところ、それは有益でしたが、主にプレイヤーの動きを扱っているようでした。私は何度も読んでいましたが、私のメソッド2コードは、Unrealエンジンで使用されているメソッドと実質的に同じであるようです。彼らは多くの詳細を提供していませんが、それはアイデアが正しいかどうか疑問に思いますが、Bulletの使用は正しくありません。
Lucas

あなたのトピックに部分的に関連する興味深い読み物:gamasutra.com/view/feature/3094/…。それはrtsに関するものであり、物理学に関するものではありませんが、サーバーとクライアントでシミュレーションを同期する必要があるポイントに達します。彼らのやり方は?彼らはクライアントとサーバーの両方で独立したシミュレーションを実行しますが、サーバーはクライアントシミュレーションが発散せず、発生した場合は修正されることを確認する送信パッケージを送信します...
tom van green

回答:


4

適切なクライアント側の予測が必要です。

Roy T.がコメントで提供したリンクの詳細をよく読んでください。プレーヤーの入力とキャラクターの物理をどうするかを説明していますが、「サーバー駆動の物理」の場合も原則は同じです。

これを実装するのは簡単ではありませんが、簡単に言えば、同期が必要なゲームオブジェクトの場合です。

  • サーバーとクライアントの両方で物理を実行します。
  • サーバーは定期的に更新を送信します。
  • クライアントは継続的かつスムーズに、物理の世界をサーバーの値に再調整します。

つまり、メソッド2で正しい方向に進んでいます。値をオーバーライドするだけでは十分ではありませんが、クライアントでジャンプが発生します。必要なのは、サーバーの値にスムーズかつ継続的に補間することです。

あなたの実際のバグについては、私はBulletに精通していませんが、いくつかの値が不足している可能性があります。たとえば、直線速度と角速度を設定したが、加速度を設定しましたか?


ありがとう!これにより、自分が正しい方向に進んでいることを実感できます。今度は、コードを細かい歯の櫛で説明します。おそらく、いくつかの通知が発生していないか、あなたが言うように、方法2は(ぎくしゃく)機能するはずなので、値がありません。
ルーカス

3

私が個人的にしていることは、ゲームをホストしている人が物理学の世界を作成し、オブジェクトをクライアントと同期することです。そのp2pネットワークスキームでも、物理エンジンをいずれかのプレイヤークライアントに基づいています。

純粋に目の保養である私が使用する他の物理学は、同期する必要さえありません。

しばらく前に作成した「ボイラーツァーカー」と呼ばれるプロトタイプでは、ホスト上で物理演算を実行し、パーティクルエフェクト(これも物理演算を使用)はネットワーク全体で同期されていませんでした。


ありがとう、ええ、それはそれについて取り組む1つの方法です。ただし、クライアントが行うものに対するクライアントでの良好な衝突応答は発生しません。また、(少なくともそのタイムステップ内で)サーバーをプッシュバックできないため、アイキャンディーは常に正しく相互作用しません。UnrealやSourceのようなエンジンがそれを行うように見えるので、これは可能であるに違いないと感じています。
Lucas

アイキャンディーは同期する必要がなく、クライアントごとに計算できます。クライアントの応答はサーバーで計算され、クライアントの座標が計算されて返送されます。衝突したことを伝えるコールバックをクライアントに送信しないでください。恐ろしいように見えます。
tsturzl 2012

2

ネットワーク同期物理の世界を実装することは不可能です。ステップNの小さな違いコースステップN + 1のはるかに大きな違いフォースまたはインパルスを適用して同期を維持し、リアルに見えるようにすることはできません。

ソリューション:-

  1. 特にキネマティックな場合は、キャラクターやレーシングカーなどのいくつかのオブジェクトのみを同期することを検討できます。しかし、世界の大部分は現実的に見えるために同期していません。

  2. サーバー上に1つの物理ワールドを設定し、オブジェクトの位置と速度をクライアントにブロードキャストできます。


物理を使ってネットワークゲームをプレイして、世界が同期していないことを確認してみてください。たとえば、ニードフォースピードワールドは無料で、マルチプレイヤーと基本的な物理学を備えています。(道路上の箱および破壊可能な物体)
最大

正確にあなたをフォローしているのかわかりません。多くのゲームではプレイヤーが木箱を投げることができるため(たとえば)、これは可能だと確信しています。オプション2は私のオプション2に似ているようですが、Bulletでオブジェクトをサーバーの位置にきれいにスナップさせることができません。多分それは私の根本的な問題ですか?
Lucas

1
いいえ。通常、同期の錯覚です。画面を比較すると、ボックスで跳ねるとボックスが異なる方向に飛ぶことがわかります。またはボックスはまったく物理的ではありません(編集されたアニメーションのみ)。箱の数が異なります。アニメーションとは、動きの背後に物理アニメーションがないことを意味します。彼らはさまざまなトリックを行って、画像を多少同期させて見えるようにしませんが、それは同期物理の世界ではありません。さまざまなゲームでの動きを見て比較する必要があります。
最大
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.