専用サーバーなしのマルチプレイヤー・ネットワークゲームでは、ゲーム中のピアのひとつがゲーム権限の中枢として機能します。このピアのことをホストと呼びます。このピアがサーバーと「ローカルクライアント」を実行するのに対し、その他のピアはそれぞれが「リモートクライアント」を実行します。
ホストが失われると、ゲームを続行することができません。ホストが失われるのは、プレイヤーがゲームを抜けた場合、ホストの処理が停止あるいはクラッシュした場合、ホストのマシンがシャットダウンされた場合、ホストのネットワーク接続が切れた場合などです。
「ホスト・マイグレーション」機能を使用すると、リモートクライアントのひとつを新しいホストにすることができるので、マルチプレイヤーゲームを継続させることが可能になります。
ホスト・マイグレーションが有効になっている場合、マルチプレイヤーゲームを実行中に、ピアのアドレスがゲーム中のピアに分配されます。ホストが失われると、ピアのひとつが新しいホストになり、その他のピアが新しいホストに接続されて、ゲームが継続されます。
新しい NetworkMigrationManager コンポーネントは、Unity Networking HLAPI を使用するマルチプレイヤーゲームにドロップすることが可能です。これによって、元々のホストが失われても新しいホストが設定されてゲームが継続可能になります。以下はエディター インスペクターの NetworkMigrationManager のスクリーンショットです。ここに現在のマイグレーションの状態が表示されます。
NetworkMigrationManager によって、NetworkManagerHUD に似たシンプルなユーザーインターフェースが提供されます。このユーザーインターフェースはテストやプロトタイピングのためのものです。実際のゲームでのホスト・マイグレーションには、カスタムのユーザーインターフェースが実装され、また多くの場合、カスタムのロジック(ユーザーによる入力なしで新しいホストを自動的に選択するなど)も実装されます。
古いホストの接続が切れたりゲームを抜けたりしたためにマイグレーションが行われた場合でも、古いホストは、新しいホストのクライアントとしてゲームに再参加できます。
ホスト・マイグレーションが行われる際、シーン内のすべてのネットワーク オブジェクトの SyncVar と SyncList の状態が維持されます。これは、オブジェクトの、シリアライズされたカスタムデータについても同様です。
ホストが失われると、ゲーム中のすべてのプレイヤーオブジェクトが無効になります。別のクライアントが新しいホストで新しいゲームに再参加すると、そのクライアントに対応するプレイヤーがホスト上で再び有効化され、他のクライアント上でオブジェクトが再生成されます。したがって、どのプレイヤーの状態データも、マイグレーション中に失われることはありません。
(注) ホスト・マイグレーション中に保持されるのは、クライアントによって利用可能なデータのみです。サーバー上にしかないデータが存在する場合、新しくホストになるクライアントはそのデータを利用することができません。したがって、SyncVar や SyncList に保存されていないホスト上のデータは、ホスト・マイグレーションが行われた後には利用不可能になります。
クライアントが新しくホストになると、コールバック関数 OnStartServer がすべてのネットワーク オブジェクトに実行されます。
新しいホスト上で、NetworkMigrationManager が関数 BecomeNewHost を使用して、現在の ClientSceneto の状態を元に、ネットワーク化されたサーバーシーンを構築します。
ホスト・マイグレーションが有効になったピアは、その connectionId
によってサーバー上で識別されます。クライアントがゲームの新しいホストに再接続されると、この connectionId が新しいホストに渡され、古いホストに接続されていたクライアントにこのクライアントがマッチされます。この Id は ClientScene で “reconnectId” として設定されます。
ホスト・マイグレーションには、クライアント権限を持った非プレイヤー オブジェクトの処理も含まれます。プレイヤー オブジェクト同様、各クライアントが持つオブジェクトが、いったん無効化されたうえで再有効化されます。
ホストが失われるまでは、すべてのピアはホストに接続されています。それぞれのピアが固有の connectionId をホスト上に持っています。この Id はホスト・マイグレーションにおいては “oldConnectionId” と呼ばれます。
新しいホストが選択されてピアがそのホストに再接続されると、各ピアによって “oldConnectionId” が提供されます。これはそれぞれのピアを識別するためのものです。これによって新しいホストは、再接続したクライアントを、対応するプレイヤーオブジェクトとマッチさせることができるようになります。
古いホストの使用は 0 の特別な oldConnectionId に再接続します - 古いホストへの接続を持っていなかったので、ホストは古いホストです。このために ClientScene.ReconnectIdHost があります。
ビルトインのユーザーインターフェースを使用する場合、oldConnectionId は自動で設定されます。これは NetworkMigrationManager.Reset あるいは ClientScene.SetReconnectId を使用して手動で設定することも可能です。
マシン A が、ホスト・マイグレーションが有効になったゲームをホストする
マシン A が失われる(したがってホストが失われる)
マシン B が マシン A からの接続を受け入れる
NetworkHostMigrationManager のコールバック関数
// called on client after the connection to host is lost. controls whether to switch scenes
protected virtual void OnClientDisconnectedFromHost(
NetworkConnection conn,
out SceneChangeOption sceneChange)
// called on host after the host is lost. host MUST change scenes
protected virtual void OnServerHostShutdown()
// called on new host (server) when a client from the old host re-connects a player
protected virtual void OnServerReconnectPlayer(
NetworkConnection newConnection,
GameObject oldPlayer,
int oldConnectionId,
short playerControllerId)
// called on new host (server) when a client from the old host re-connects a player
protected virtual void OnServerReconnectPlayer(
NetworkConnection newConnection,
GameObject oldPlayer,
int oldConnectionId,
short playerControllerId,
NetworkReader extraMessageReader)
// called on new host (server) when a client from the old host re-connects a non-player object
protected virtual void OnServerReconnectObject(
NetworkConnection newConnection,
GameObject oldObject,
int oldConnectionId)
// called on both host and client when the set of peers is updated
protected virtual void OnPeersUpdated(
PeerListMessage peers)
// utility function called by the default UI on client after connection to host was lost, to pick a new host.
public virtual bool FindNewHost(
out NetworkSystem.PeerInfoMessage newHostInfo,
out bool youAreNewHost)
// called when the authority of a non-player object changes
protected virtual void OnAuthorityUpdated(
GameObject go,
int connectionId,
bool authorityState)
サーバー(ホスト)のみに存在していたデータは、ホストの接続が切れると失われます。ホスト・マイグレーションが正常に実行されるためには、重要なデータを(サーバー上だけに保管するのではなく)クライアントに配信する必要があります。
上記は、ゲームが直接接続を使用している場合に当てはまる説明です。マッチメーカーやリレーサーバーを使用している場合には、追加の作業が必要となります。