TrueSync チュートリアル セクション4
チュートリアルの内容
このチュートリアルのシリーズでは、Photon TrueSyncを使ってUnityでシンプルなマルチプレイヤーゲームを作る方法を説明します。セクション1〜3では、Photonに接続するための基本的な設定とコード、物理ベースのプレイヤー制御ゲームオブジェクトの作成方法、ゲームオブジェクトを確定論的にインスタンス化して破壊する方法を説明しました。
セクション4の内容:
プレイヤー制御ボックスからのレスポンスの速い、低レイテンシーのマルチプレイヤーゲームクライアント。プレイヤーは、ボックスを移動させて、より速い反応時間でお互いに撃つことができます。
ロールバックの利用
ゲームプレイのコードは完成しましたが、キー入力とプレイヤーボックスのレスポンス(動きまたは射撃)の間に大きな遅れがあります。
これは、TrueSyncがロックステップシステムであり、シミュレーションを実行する前にリモートプレイヤーの挙動が受信されるのを待つために入力キューがローカルプレイヤーの挙動にレイテンシを追加するため、発生します。
アクションゲームによっては、この遅れがプレイヤーのプレイに有害である可能性があるので、これを補うためにロールバックシステムを開発しました。
ロールバックシステムは、リモートプレイヤーの入力が受信される前であっても、ローカルシミュレーションを進めます。そうすることで、ローカルオブジェクトのレスポンス時間が向上します。そのために、TrueSyncはリモートプレイヤーの入力値を予測します。
実際のリモート入力が受信された時には、TrueSyncはそれを予測値と比較し、次の規則に従って動作します:
- 実際の入力が予測値と同一の場合:シミュレーションを正常に進めます。
- 実際の入力が予測値と異なる場合:以前の状態にシミュレーションを復元(ロールバック)し、事前に、間違ってシミュレートされたすべてのティック/フレームを直ちに再シミュレートします。
ロールバックシステムは、マルチプレイヤーゲームのレイテンシを隠す有力なメカニズムです。さて、TrueSyncゲームでこの機能を有効にする方法を見てみましょう。
TrueSyncのグローバル設定
"TrueSync/Unity/Resources"フォルダ内にグローバル設定アセットがあります。
以下の変数を理解しておくことが重要です:
- sync window:入力キューのサイズ;
- rollback window:TrueSyncが予測入力値でシミュレーションを進めることができるフレームの最大量;
- panic window:レスポンスがないために(入力値を送信していない状態)リモートプレイヤーがシミュレーションから削除されるまでの間に失われたフレーム/ティックの最大量;
- Lock Time Step:TrueSyncのゲームループの1フレームあたりの時間;
ゲームクライアントがPhoton Cloudサーバに対して60msのping(往復時間)を持つとし、デフォルトのロックステップ時間0.02(1フレームあたり20ms)を使用しているとします。
ロックステップゲームでは、リモートプレイヤーの遅れを入力キューが補うために、それに等しい大きさの遅延をローカル入力に加える必要があります。
これは、同期ウィンドウのサイズが少なくとも3であることを意味するので、すべての入力に60ms(3フレーム x 20ms/フレーム)を追加します。
ロールバックでレイテンシを隠蔽
pingが大きく変動する可能性があるため、より安全な値は5または6の同期ウィンドウになります。ただし、これはゲームによっては大きすぎる可能性があるため、代わりにロールバックウィンドウを大きくするオプションがあります。
4の同期ウィンドウと4のロールバックウィンドウを使用すると、8フレームのレイテンシー保護(つまり160ミリ秒のピークping時間でもスムーズに動作する)をゲームに与えます。
グローバル設定を変更し、これらの値(4と4)をそれぞれ同期ウィンドウとロールバックウィンドウに使用します(同期ウィンドウのデフォルト値10を削除)。
ゲームシーンを試してみましょう。プレイヤーボックスの反応が上がったことに注目してください。2つのビルドを使ってオンラインテストを行いその結果を見ることもできますが、死亡スコアとcooldownタイムに問題が発生する可能性があります(次にこれを改善します)。
状態管理の追加
ロールバックの問題の1つは、TrueSyncの内部物理エンジンなどの状態を復元することに加え、HP、スコア、XP、カウンタ、タイマーなどの、シミュレーションに追加するカスタム変数を管理する必要があることです。
予想された入力値でシミュレーション中に発射体がプレイヤーのボックスに当たり、それがrespawnされ、死亡カウンターが上がることをイメージしてください。
ロールバックが必要で、実際の入力値を受信したところ、プレイヤーが投射物を避けたためプレイヤーボックスがヒットされなかったとします。 respawnは、物理状態の復元によって正しく上書きされますが、死亡カウンターは上書きされず、シミュレーションが間違った値で進行してしまいます。
このような問題を回避するために、TrueSyncには状態管理システムがあります。開発者はロールバック中にカスタムの属性またはオブジェクトを追加して、それを自動的に監視し、以前の値に復元することができます。
チュートリアルでは、ロールバックを安全に使用するために、次の属性を追跡する必要があります。
- PlayerWeapon.cs内の武器のクールダウンタイマー;
- Projectile.cs内の発射体破壊タイマー;
- PlayerMovement.csの死亡カウンター;
TrueSyncの状態管理システムに属性を追加するには、 "[AddTracking]"注釈を追加して、そのコンポーネントを状態追跡リストに登録します。以下のコードは、 "Projectile.cs"スクリプトの一部を示しています。他の2つの属性にも同じ処理を行います。
C#
[AddTracking]
private FP destroyTime = 3;
最終テスト
両方のシーン (Tutorial/Menu とTutorial/Game) がビルド設定に含まれていること、また、Tutorial/Menuが最初のシーン(起動時にUnityが読み込むもの)であることを確認してください。
任意のビルドを作成し、1つ、または2つのコピーを実行して、Unityエディタ内からMenuシーンを実行します。
これで、両方のクライアントがPhotonに接続して、各クライアントが独自のボックスを制御し、互いに射撃し合うゲームシーンが読み込まれます。プレイヤー入力の反応は以前より速くなっているはずです。
チュートリアルのソース
チュートリアルの完全なソースは、こちらのUnity Package Downloadからダウンロードできます。
ソースにはTrueSyncとPUNが含まれていないので、パッケージを使用するには、すでにTrueSyncライブラリが含まれているプロジェクトにパッケージをインポートしてください。
Back to top