特定のNetwork Viewで状態同期を有効にするには,State SynchronizationのドロップダウンでReliable Delta CompressedかUnreliableを選択します。次に同期するデータの種類を_Observed_プロパティとして設定します。
UnityはTransform,Animation,RigidbodyおよびMonoBehaviourコンポーネントを同期できます。
Transforms は位置,回転,スケールを格納することによりシリアライズされます。親子情報はネットワークを通して渡されることはありません。
Animation は各アニメーション実行の状態をシリアライズします,すなわちtime,weight,speedおよび有効化されたプロパティです。
Rigidbody は位置,回転,速度および回転速度をシリアライズします。
スクリプト(MonoBehaviours)はOnSerializeNetworkView() 関数を呼び出します。
Network Viewには2つの信頼性レベル,すなわちReliable Delta CompressedとUnreliable,があります。
どちらにも長所,短所があり,このゲームの詳細により何を使用するのがベストか決まります。
帯域幅を最小化するための追加情報については,ネットワーク帯域幅の最小化 を参照下さい。
Reliable Delta Compressedモードによりデータは最後にクライアントで受信したデータと現在の状態のデータを自動的に比較します。もし最後の更新からデータが変更されてない場合データは送信されません。しかしデータはプロパティごとに比較されます。例えば,もしTransformの位置が変更されているが回転は変更されてない場合,位置のみがネットワーク上送信されます。変更データのみ送信することで帯域幅は節約されます。
Unityは全ての送信されたパケットが受信されていることを,UDPパケットが受信されるまで再送信を繰り返すことにより,信頼性を保って送信します。言い換えると,パケットが受信できなかった場合,その後に送られるパケットは受信できなかったパケットが,再送信されて到着するまで,適用されないとうことです。それまでは,それ以降のパケットはバッファで待機します。
Unreliableモードにより,Unityはパケットが受信されたかどうかを確認することなく送信します。これによりどの情報が受信されたか判断できないため,変更データのみを送信することは安全ではなく,毎回の更新ごとに状態の全てが送信されます。
ネットワークレイヤーではUDP,すなわち信頼性がなく順序がないプロトコルが使用されますが,TCPのように信頼性があり順序のあるパケットを送信することも出来ます。内部的にACKやNACKを使用してパケットの送信を制御しパケットが受信されることを保証します。信頼性があり順序のあるパケットを使用するデメリットはパケットが受信されないか遅延した場合,そのバケットが安全に到着するまで全てが停止されてしまうことです。これはタイムラグの大きいネットワークでは遅延が認識されることにつながります。
信頼性のない送信はデータがどうせ毎フレーム変更されることが分かっている場合に便利です。例えば,レーシングゲームで,プレイヤーの車は必ず動いているといえるので,パケットを逃したとしてもすぐに次のパケットで修正されます。
一般的には,「Unreliable」(非信頼)を,素早く頻繁な更新を行うことが重要であって,パケットを逃して問題ない場合に使用します。反対に,データがそれほど頻繁に変更されない場合は,「Reliable Delta Compressed」(信頼差分圧縮)を,帯域幅の節約のために使用します。
データがゲーム世界の状態に対して完全な権限 がある場合,クライアントはサーバから受信する更新にもとづいてゲーム状態を変更します。これによるひとつの問題はサーバが反応するまで待つ遅延はゲームプレイに悪い影響を与えることです。例えば,プレイヤーがキーを押して前に進む場合,実際には更新された状態がサーバーから受信しないかぎり動きません。この遅延は接続の待ち時間に依存するため,最悪の場合接続が遅いほど,制御系も,きびきびとはしなくなります。
この問題に対する解決策のひとつはClient-side Prediction(クライアント側予測)であり,この意味はクライアントがサーバから渡される動作を,ほぼ同一モデルをしようすることによって予測することです。プレイヤーは直ちに入力に反応するもののサーバは最後の更新からの情報をみます。状態の更新がサーバから到着したとき,クライアントは必要な情報だけ認識します。予測の誤りは判明の都度修正され,連続的に修正されれば結果はよりスムーズとなりより気づかないものとなる。
クライアント側予測の基本原理をプレイヤーの相手に適用することもできます。Extrapolation(外挿)は相手の位置,速度,角度について最後に知っている複数の情報を格納して,近い将来にいる場所を予測するプロセスです。次の更新がようやく受信されたときに正しい位置が判明し,クライアントの状態は正確な情報で更新され,この場合に予測が悪かった場合はキャラクターの位置が飛んで見えてしまいます。FPSゲームにおいてプレイヤーの動作は一貫性がないことが多く,この種の予測がうまく行くことは難しい。遅延が十分に大きくなってしまうと予測のエラーが蓄積するにつれ相手の位置がひどく飛ぶようになります。
Interpolation(内挿)はパケットがクライアントへの送信後に受信されない場合に使用できます。通常,これはNPCの動作がポーズし,新しいパケットが受信されたときに新しい位置にジャンプすることにつながります。ゲームの世界の状態を一定の量だけ(例えば100ms)遅延させて,それから最後に知られた位置と新しい位置の間に内挿することで,このパケットが受信できなかったタイミングでの,二点間の動作はスムーズになります。