Version: 2017.3
高度な状態同期
ネットワークでの可視性をカスタマイズ

ネットワークでの可視性

マルチプレイヤーゲームでは ネットワークでの可視性 という概念を使用して、ゲーム中の任意の時点でどのプレイヤーがどのゲームオブジェクトを見ることができるかを判断します。視点の移動やゲームオブジェクトの移動があるゲームでは、ゲーム内で起こっていることすべてを一度に見ることができないのが一般的です。

特定のプレイヤーがゲーム中の特定の時点で、ゲーム内の他のプレイヤー、ノンプレイヤーキャラクター、他の動いているものやインタラクティブなものの大部分を見ることができない場合、通常、ホストはそれらの情報をプレイヤーのクライアントへ送る必要はありません。

これは、以下の 2 つの利点があります。

  • プレイヤー間でネットワークを通してやり取りする データ量 を削減します。これにより、ゲームの反応性を向上させ、帯域幅の使用を削減できます。マルチプレイヤーゲームがより大規模で複雑になるほど、この問題はより重要になります。

  • また、ハッキングの防止 にも役立ちます。プレイヤークライアントは、自分にとって可視である情報しか持たないため、そのプレイヤーのコンピューターがハックされてもそれ以外の情報が奪われることはありません。

ネットワークの概念における「可視性」は、必ずしも、ゲームオブジェクトが画面上で直接見えるかどうかには関係しません。そうではなく、任意のゲームオブジェクトに関するデータを特定のクライアントに送信すべきか否かに関係します。簡単に言えば、クライアントがあるゲームオブジェクトを「見る」ことができない場合は、そのゲームオブジェクトに関する情報をネットワーク経由で送信する必要はありません。ネットワークを通して大量の不要なデータを送信すると、ネットワークパフォーマンスの問題が発生することがあるため、理想的には、ネットワーク経由で送信するデータは必要なものだけに制限すべきです。

しかし、ゲームオブジェクトが任意のプレイヤーに本当に見えるかどうかを正確に判断することは、リソースに負担がかかり複雑です。そのため、プレイヤーにゲームオブジェクトに関するネットワーク化されたデータを送信するかどうか (つまり、それが「ネットワークで可視」かどうか) を判断するために、より簡単な計算をしたほうが良いことがしばしばあります。これらを考慮して、可視性を決定する計算の複雑さのコストと、必要以上に多くの情報をネットワーク経由で送信するコストとの良いバランスを実現することが必要です。計算の簡単な方法の 1 つに距離 (近接) チェックがあります。Unity はこれを目的としたビルトインのコンポーネントを備えています。

Network Proximity Checker コンポーネント

Unity の Network Proximity Checker コンポーネントはプレイヤーのネットワークでの可視性を実装するもっとも簡単な方法です。Network Proximity Checker は物理システムと一体化してゲームオブジェクトが近接しているかどうか (つまり、マルチプレイヤーゲームにおいて、ネットワークメッセージを送信す目的で「可視」であるか) を判断します。

The Network Proximity Checker コンポーネント
The Network Proximity Checker コンポーネント

このコンポーネントを使うには、ネットワークでの可視性を制限したいネットワーク化したゲームオブジェクトのプレハブに加えます。

Network Proximity Checker には設定可能な可視性に関する 2 つのパラメーターがあります。

  • Vis Range は距離のしきい値を制御します。その値以内である場合、ネットワークはゲームオブジェクトがプレイヤーにとって可視であると判断します。

  • Vis Update Interval は、距離をテストする頻度を制御します。値は次のテストが行われるまでの間隔を秒で表しています。これによって、テストの頻度をできる限り少なくし、確認の最適化をすることができます。値が低いほど、更新回数が多くなります。ゆっくりと動くゲームオブジェクトに関しては、この間隔を高い値に設定します。素早く動くゲームオブジェクトに関しては、この間隔を低い値に設定します。

Network Proximity Checker を利用するゲームオブジェクトには Collider コンポーネントをアタッチする必要があります。

リモートクライアント上のネットワークでの可視性

リモートクライアント上のプレイヤーがネットワーク化されたゲームに参加すると、プレイヤーにとってネットワークで可視のオブジェクトのみが、そのリモートクライアントにスポーンされます。したがって、ネットワーク化された多くのゲームオブジェクトを持つ大きな世界にプレイヤーが入ったとしても、ゲームを素早く始めることができます。なぜなら、ゲーム世界に存在するすべてのゲームオブジェクトをスポーンする必要がないためです。この処理はシーン内のネットワーク化したゲームオブジェクトに適用されますが、アセットのロードには影響しません。保存したプレハブやシーンのゲームオブジェクトのアセットをロードする時間は必要です。

プレイヤーが世界の中で移動すると、ネットワークで可視なゲームオブジェクトのセットが変更されます。プレイヤーのクライアントは、これらの変更が発生すると通知を受けます。ObjectHide メッセージはゲームオブジェクトがネットワークで可視でなくなったときにクライアントに送信されます。デフォルトでは、このメッセージを受け取ると、ゲームオブジェクトは破棄されます。ゲームオブジェクトが可視になると、Unity が初めてオブジェクトを作成したときのように、クライアントは ObjectSpawn メッセージを受信します。デフォルトでは、ゲームオブジェクトは他のスポーンされたゲームオブジェクトのようにインスタンス化されます。

ホスト上のネットワークでの可視性

ゲームをホストしているプレイヤーにとってサーバーとクライアントの両方の役割をするため、サーバーと同じシーンを共有します。このため、ローカルプレイヤーにとって可視でないゲームオブジェクトを破棄することができません。

代わりに、NetworkBehaviour の仮想関数 OnSetLocalVisibility が呼び出されます。このメソッドは、ホスト上でその可視性の状態が変わったすべてのゲームオブジェクトの NetworkBehaviour スクリプトで呼び出されます。

OnSetLocalVisibility のデフォルトの実装は、ゲームオブジェクトのすべての Renderer コンポーネントを無効/有効にします。この実装をカスタマイズしたい場合は、スクリプトのメソッドをオーバーライドし、ゲームオブジェクトがネットワークで可視/不可視になるときのホストの反応の仕方 (HUD 要素やレンダラーの無効化など) に関して新しい挙動を与えることができます。

高度な状態同期
ネットワークでの可視性をカスタマイズ