ステート転送
イントロダクション
Fusionは多くのネットワークアーキテクチャに対応しており、それらのアーキテクチャのすべてはステート転送に頼っています。 Fusionは簡潔さを念頭にビルドされ、デルタ圧縮やクライアントサイド予測、ラグ補正などの高度なステート転送機能を搭載しながら、Unityワークフローに自然と繋げることができます。
ステート転送プライマー
「ステート転送」という言葉は、すべてのクライアントにゲームステートを配布する方法を意味します。 ステート転送アーキテクチャでは、ゲームステートはサーバからクライアントに転送されます。 ステートにはクライアントがゲームステートをローカルで複製するのに必要なすべてが含まれています。 FusionはゲームステートをNetworkBehaviours
として知られる専門のMonoBehaviours
のプロパティを通して顕示します。 ある特定の瞬間(tick)での、全てのネットワークゲームオブジェクトの[Networked]
プロパティの完全なセットをSnapshotといいます。
Fusionで使用しているステート転送モードは以下の2つです。
1、デルタ圧縮(DC)。完全なスナップショットを圧縮して送信する。
2、結果整合性(EC)。インタレスト管理フィルタを使用して、完全なゲームステートのどの部分を、各クライアントに送信するスナップショットに含めるか決定する。
どちらにしても、ネットワークレイテンシの関係で、調整されたステートは、クライアントが受け取るときには既に古いものとなっています。 これを補正するため、Fusionはローカルの[Networked]
プロパティの状態を、直近に受信した状態から、以前のアップデートで予測された最後のティックまで(およそスナップショットティック+RTT)再シミュレーションします。
結果整合性モードでは、受信データは合計ネットワークステートの一部サブセットのみとなります。 これは、与えられたNetworkObject
のセット上の同じプロパティによって常にステートが顕示されることになるため、アプリケーションからは透過的です。
クライアント vs サーバーオーソリティ
Fusionは2種類のオーソリティモードで実行できます。
- サーバーオーソリティモード: クライアントの1人がサーバーとクライアントの両方を受け持つ、専用ヘッドレスUnityインスタンスのある厳密なクライアント・サーバーセットアップ。
- クライアントオーソリティモード: 各クライアントが自身のオブジェクトに対して完全なオーソリティをもつ。
クライアントオーソリティモードでは再シミュレーションがなく、すべてのクライアントがいつも
圧縮
ステート転送の明らかなデメリットは、帯域幅使用量です。 Fusionでは、ネットワーク上のゲーム状態の変更のみを送信し、そのデータに最小限のビットレベルの表現を選択することで、パッケージサイズを大幅に削減しています。結果整合性の場合は、さらに削減して、受信者に関連する変更のみを含んでいます。
### 精度
効率的にデータを圧縮する主要な側面はAccuracy
です。 Fusionでは、NetworkProjectConfig > Accuracy Defaults
でグローバルに設定できます。また個別の変数には [Accuracy]
属性を使用します。
Fusionでは、Accuracyを浮動点数を整数に変換するのに使用しています。 例えば、0.00から1.00など小数点2桁の精度の浮動の代わりにFusionでは、 0から100の整数を1つ保管します。 値が必要とするメモリ使用量は変わりませんが(4バイト)、圧縮の効率が上がるため帯域幅の節約になります。 全てのネットワークプロパティに意味のある制度を選択することで転送フットプリントを削減できます。
### デルタ圧縮
前の章で定義した精度を使用して、デルタは送信される必要のある実際のビット数を削減する形で圧縮されます。こうして、4バイトの整数に置き換えられた4バイトの浮動が、密度が上がることでわずか数ビットに削減されるのです。
デルタ圧縮は、クライアントが受け取ったっことが確認されている最後のティックの合計ステートと細心のティックのステートを差異を計算します。 例えば、サーバーがクライアントからティック95を受信した確認をとっていたとして、サーバー自身のティックが100の場合、次のデルタは5ティック程度で計算されることになります。
サーバーがクライアントから確認を受信するまで、デルタは大きくなり続けます。これにより、送信パッケージが冗長になることがあります。 効率が悪いように見えますが、「ロストパケット」の心配がないという莫大なメリットがあります。 クライアントが受信したデルタがどのようなものであったとしても、クライアントのその時のステートに常に適用されます。 古いデルタが遅れて表示された場合、現在のステートに影響を与えることなく、また、遅延を引き起こす回復手順を必要とすることなく、単にドロップされます。
Fusionは事実上、少しの帯域幅と引き換えに、ワーストケースのレイテンシを非常に大きく削減しています。
##インタレストマネジメント
Fusionが結果整合性モードで動作するように設定されている場合、APIを利用して各プレイヤーに送信するデータを管理することで、必要な帯域幅をさらに削減することができます(これは一般的に「インタレストマネジメント」と呼ばれています)。
これにより、個々のプレイヤーの世界観に影響を与えることなく、有線で送られるデータ量を劇的に減らすことができます。 これは、ゲームをプレイ可能な状態にするのにインタレストマネジメントが不可欠であることが多い、多くのプレイヤーが参加する大規模なゲームの世界では特に顕著です。
ネットワーク上のゲームオブジェクトに対するプレイヤーのインタレストリストを管理する方法は3通りあります。
- 関心領域 (1人のプレイヤーに多数)
- グローバルオブジェクト(全プレイヤー向け)
- カスタムインタレストマネジメント(プレイヤーとオブジェクトのペア毎)
### 関心領域
関心領域は、AoIとも言われますが、世界空間の球体を定義し、その中のNetworkObject
を自動的にデータ転送に加えます。 これは、プレイヤーの視界距離に合わせた半径を持つ、プレイヤーのアバターの周りの単一の球体であったり、プレイヤーが最新の情報を必要とする場所(例えば、ミッション・オブジェクティブの周辺)であったりします。
プレイヤーのAoIの指定は、NetworkRunner
のシンプルなAPI呼び出しです。
C#
Runner.AddPlayerAreaOfInterest(PlayerRef player, Vector3 worldPosition, float radius);
注意:Shared Mode
で使用している半径は固定で、 NetworkProjectConfig
で設定されています。
ServerMode
とHostMode
では、サーバー/ホスト上のFixedUpdateNetwork()
で毎フレーム呼び出されます。クライアントから呼び出された場合、プレイヤーの参照はローカルのプレイヤーでなければなりません。これは、AOIの責任がPhoton Cloudによって処理されるClient Authority
モードでのみ意味があります。
AoIの対象となるネットワークオブジェクトをサーバーが把握するために、また、特にPhotonクラウドがワールド内のオブジェクトの位置を把握するために(Unityのシーングラフは理解していないため)、ゲームオブジェクトは事前に構築された特定のバリエーションのNetworkBehaviour
を使用する必要があります。
そのバリエーションは、NetworkTransform
、NetworkRidigBody
、NetworkCharacterController
です。
###グローバルオブジェクト
AoIの空間表現に加えて、NetworkObject
コンポーネントでオブジェクトをglobal
としてマークすることができます。 これにより、ワールドの位置に関わらず、すべてのプレイヤーのAoIにグローバルオブジェクトが含まれるようになります。
###カスタムインタレストマネジメント
個々のプレーヤーは、常に興味のあるオブジェクトを持っている可能性があります。 NetworkObject
のデータが常にプレイヤーに送信されるようにするには、SetPlayerAlwaysInterested()
を一度送信します。
C#
Runner.SetPlayerAlwaysInterested(PlayerRef player, NetworkObject obj, bool always)
## ネットワークトポロジー
Fusionは複数のネットワークトポロジーに対応しています。
###専用サーバー
Unity のヘッドレスインスタンスを完全なサーバー権限でデプロイします。 これは典型的なクライアント/サーバー型の設定で、物理オブジェクトやレンダリングプリミティブ(これらが使用されていなくても)を含むゲームワールドの完全な知識を持つ、信頼できるオーソリテーティブエンティティを持つことがメリットです。 専用サーバーは通常、パブリックな固定IPでホストされているため、UDPホールパンチングやネットワークリレーの必要はありません。
専用サーバーの主なデメリットはゲームセッションごとに完全なUnityインスタンスを立ち上げるコストがかかることです。
###プレイヤーホスト型
プレイヤーホスト型サーバーモードでは、パンチスルーとリレーがフォールバックとして組み込まれており、Photon Cloudが提供する完全なホスト移行サポートも含まれています。 UDPホールパンチングが失敗し、Fusionがピア間の直接接続を確立できない場合、プレイヤーはリレーを介して接続する必要があります。これは散発的な現象で、10人に1人程度の割合で発生します。 リレーは、プレイヤーホスト型においてさらなるレイテンシーの原因を引き起こしかねませんが、ゲームプレイの観点からはほとんど気になりません。
プレイヤーホスト型モードでは、ローカルインスタンスはサーバーであり、クライアントではありません。
このモードでは、ローカルプレーヤーの使用が可能で、入力をポーリングし、期待通りにレンダリング時に補間を行います。
このモードは、全体的には専用サーバーと同等です(つまり、ゲームコードに目立った変更はありません)。
このモードでは、専用サーバーのコストがかかりませんが、信頼のおけるオーソリティが犠牲になり、言い換えれば、不正なホストがチートを行う可能性があります。
### シングルプレイヤー
Fusionでは、ネットワークコードを変更せずにローカルで実行することができます。
プレイヤーホスト型モードと同様のロジックで実行されますが、外部ネットワーク接続を開くことはありません。 これにより、ゲームモードの際にアプリケーションが延々と切り替えを行う必要がなくなりました。
共有モード
結果整合性(EC)を使用したデータ駆動型のサーバー管理スナップショットによるPhoton Cloudに対するクライアントの権限と利害関係の管理は、プレイヤー数が多い時にも対応します。 共有モードでは、Photon Cloudを使用して、完全なUnityインスタンス実行のための膨大なオーバーヘッドなしに、専用サーバーのメリットを実現しています。
Back to top