Network View
Compnent ⇛Miscellous⇛NetworkViewでゲームオブジェクト(プレーヤー)にアタッチします
プロパティ
State Synchronization ネットワークビューで使用される 同期の種類
Off:
状態の同期は使用されません。
Reliable Delta Compressed:
状態が変わっていない場合には何も追加されずに送信されます。パケット損失の場合、失われたパケットは自動的に再送信されます
Unreliable:
完了状態が送信されます。より多くの帯域幅を使用しますが、パケットロスの影響が最小限に抑えられます
Observed:
ネットワークを経由して送信されるデータ
View ID: このネットワークビューの識別子。
Scene ID:このシーンでネットワークビューのID 番号
Type:実行時 に シーンまたは割り当てのいずれかに保存される
Reliable Delta Compressed またはUnreliableのデータ観測コンポーネントが自動的にネットワーク経由で送信されます
パケットは 常に送信された順序で受信されます。パケットが廃棄されている場合は、そのパケットが再送信されます。以前のパケットが受信されるまでそれ以降のすべてのパケットがキューに入れられます。最後のトランスミッションの値と現在の値が異なる場合は送信され 差がない場合は何も送信されません。
※ 変換、アニメーション、剛体、またはスクリプト。どのような種類のコンポーネントでも観測できます
(インスペクタから値をobservedへドラッグドロップ)
● NetworkView.isMine
・・・変数を使用してオブジェクトによって制御されるネットワークビューが送信する自分自身かの判別ができます
function OnNetworkInstantiate (info : NetworkMessageInfo) {
if (networkView.isMine)
Debug.Log("New object instanted by me");
else
Debug.Log("New object instantiated by " + info.sender);
}
手動でNetworkIDを設定する方法
●Network.AllocateViewID()
時々Network.Instansiateでセットアップがうまく動作しないことがあり そうした場合自分でNetworkViewIDを
割りつけてやる必要があります。
http://docs.unity3d.com/Documentation/ScriptReference/Network.AllocateViewID.html
EX)
var cubePrefab : Transform;
function OnGUI () {
if (GUILayout.Button("SpawnBox")) {
var viewID = Network.AllocateViewID();
networkView.RPC("SpawnBox",
RPCMode.AllBuffered,
viewID,
transform.position);
}
}
@RPC
function SpawnBox (viewID : NetworkViewID, location : Vector3) {
// Instantate the prefab locally
var clone : Transform;
clone = Instantiate(cubePrefab, location, Quaternion.identity) as Transform;
var nView : NetworkView;
nView = clone.GetComponent(NetworkView);
nView.viewID = viewID;
}
送信周期の変更
※ “Edit → Project settings → Network”
Sendrate: 1秒間に何回のネットワークメッセージが送られるかの設定。 ※RPCメッセージに影響しません。
(ゲームが処理落ちしない最低限のトラフィックに調整してください)
スクリプトの変数の同期
■OnSerializeNetworkView (stream : BitStream, info : NetworkMessageInfo)BitStream ・・・ ステータス及び送信データのセット
● isReading ・・・BitStreamがデータ読み込み状態か?
● isWriting ・・・BitStreamがデータ書き込み状態か?
● Serialize ・・・bool, char, short, int, float, Quaternion, Vector3 , NetworkPlayer.型などの値が返る
NetworkMessageInfo ・・・ 送信相手は誰か 送信された時間などの情報を受け取れます
● timestamp ・・・送信されたメッセージの秒単位でのタイムスタンプ
● sender ・・・誰からメッセージが送信されたのか 返り値はNetworkPlayer
EX)
var currentHealth : int;
function OnSerializeNetworkView(stream : BitStream, info : NetworkMessageInfo) {
var health : int = 0;
if (stream.isWriting) {
health = currentHealth;
stream.Serialize(health);
} else {
stream.Serialize(health);
currentHealth = health;
}
}
| トラフィックの限度:スコープとグループの制限 |
送信するデータの量の制限によりネットワーク性能を大幅に改善することができます。
マルチプレイの環境ではプレーヤーは、情報のすべてのビットを受け取る必要はありません。
networkviewコンポーネントにはSetScope機能とgroup 設定があります
●NetworkView.SetScope (player : NetworkPlayer, relevancy : bool) : bool
開始時 すべてのプレーヤーのためのデフォルトはtrueに設定されます。
たとえばプレーヤーからNetworkViewを設定したオブジェクトが十分遠くにあり情報を受け取る必要がない場合
値をfalseに設定すればNetworkViewを通じたデータ送信は行われません。 ※RPCには作用しません。
●NetworkView.group ※groupナンバーはint型
すべてのネットワーク・メッセージやRPCの呼び出しで、設定されたグループ番号へ送信します。
※グループ番号の最大は32
function Awake() {
// Send everything from this network view through group 1
networkView.group = 1;
}グループごとの送信を制限するための関数
●SetReceivingEnabled (player : NetworkPlayer, group : int, enabled : bool) : void
・・・データ受信の可否
●SetSendingEnabled (group : int, enabled : bool) : void
・・・データ送信の可否
この2つの関数で 送信・受信の制限をすることができます。 たとえばゲームが32のレベルマップにわかれている場合 プレーヤーの周囲8方向のタイルにだけデータを送信することができます。 FPSなどでは必要ないかもしれませんがUnityのライブラリでMMOなどの大規模なゲームを作成する場合はこの機能が必要になってきます。
| Unityエディタのオプション |
■ “Edit → Project settings → Network”
Sendrate: 1秒間に何回のネットワークメッセージが送られるかの設定。RPCにはメッセージに影響しない。
ゲームが処理落ちしない最低限のトラフィックに調整してください
Debug level: ネットワークデバッグ情報のログ表示切替
■“Edit → Project settings → Player”
Run in background : サーバーをバックグラウンドで実行する
| ネットワーク接続のセキュリティ |
AES 暗号化, CRCs, ランダム暗号化、SYNCookies 、 RSA暗号化
ひとつのコードで全てのセキュリティが有効になります
function StartServer ()
{
Network.InitializeSecurity();
Network.InitializeServer(32, 25000);
}
InitializeSecurity()をサーバに一度だけイニシャライズするだけです。15バイト分のパケット送信が追加されます。
| チート対策 |
ゲームを設計する場合、常に最悪のシナリオを仮定するべきです。
プレーヤーをコードに関して自分と同じだけ知っていると仮定します そして彼らは最悪にネットワーク・パケットの値を編集することができるとします。 したがって、受け取る値をすべて常にチェックします。
チートと格闘するためには特別のコードを必要としません 。 賢いゲーム/ネットワーク設計をするだけです。
| プロキシの使用 |
リンク先を参照のこと
http://unity3d.com/support/documentation/ScriptReference/Network-useProxy.html
| ラグの解消 : 予測、extrapolation と interpolation |
エネミーにプレーヤー予測と同じ原理を適用することは可能です。
extrapolationは、最後に(バッファーされた)既知の位置、速度および方向でプレーヤーが次のフレームでどこに位置するかを予測します。
interpolationはパケットがクライアントへ行く途中にいつ落とされるかということです。相手は通常休止して新しいパケットが到着する時、最新の位置へ移動します。
あるセット量の時間(100ミリセカンドのような)までにゲームの状態を遅らせることによって、新しい最後の位置を挿入することでこれらの2点間の移動はパケットが落ちても滑らかに見えます。
さらにより正確な同期をさせるためにネットワークsendrateオプションを上げることで対応できます。
次回の記事で補足します
| Network Loading |
ネットワーク通信の間すべてのサーバー/クライアントPCの上で滑らかに動きます。
新しいクライアントがゲーム・ロビー場面で接続している一方で、ゲームを実行するサーバーを持つことができることを意味します。
これはサーバーがクライアントにAllBufferdでゲームオブジェクトの生成を送信をする時を以外問題はありません。
ゲームをロードする間には一時的なクライアント上のネットワーク通信をシャット・ダウンできます。
これはクライアント上で、サーバー接続が成功した直後に Network.isMessageQueueRunning = false; を呼ぶことにより行うことができます。
サーバーは、ネットワーク・グループを賢く使えば多数のゲーム・セッション/複数レベル(同じ場面でも)をhostすることができます。
※ 異なるゲーム・セッションでのプレーヤー間の衝突だけ注意してください。
| ネットワーク開発のための外部リソース |
ネットワークの知識を深めたい人は見てください
● http://202.16.132.23/unity3docsj/Documentation/Documentation/Components/net-HighLevelOverview.html
『Unityで使える非同期処理のクラスライブラリ(iterator-tasks)を公開しました』
Aimingの開発者さんのブログ http://developer.aiming-inc.com/
ここに載せるのはちょっと違うような気もするのですが イテレータを使用して処理を複数のコルーチンに分散化して通信処理の遅延を解消する(たぶんそういうことかと)ライブラリだそうです。
そこまで遅延したことがないのですが巨大なMMOタイプだと必要になるのかな
| Unityのネットワークサーバ |
マスターサーバー
マスターサーバーは、ゲームマッチする手助けをします。サーバーを起動する際マスターサーバーに接続し、全てのアクティブなサーバーのリストを提供します。
http://www.unity3d.com/master-server/index.html
●要するにUnityのマスターサーバーはマルチプレイゲームのマッチングを行うサーバーで ゲーム自体はそれぞれのプレーヤーをP2P接続するものということみたいです。最初にゲームを立ち上げたプレーヤのPCがHOSTになり その後ゲームにインしたプレーヤがクライアントになるというわけですね。
マスターサーバーのカスタム記事はここらへん⇓を参考にしてください (力つきました・・
http://d.hatena.ne.jp/nyakagawan/20110729/1311933651
http://d.hatena.ne.jp/shinriyo/20110929
| その他のネットワークミドルウェア |
Unityのネットワーク接続に利用できるミドルウェアのリンクです
