ノート: UNet は非推奨となり、今後 Unity から削除される予定です。新しいシステムが開発中です。詳細は ブログ と FAQ を参照してください。 |
状態同期とは、ネットワーク化されたゲームオブジェクトのスクリプトに属する整数、浮動小数点数、文字列、ブール値などの値の同期を意味します。
状態同期 (State synchronization) は、サーバー からリモートクライアントに対して行われます。ローカル クライアントはシーンをサーバーと共有するため、ローカルクライアント用にシリアライズされたデータを持ちません。ただし、SyncVar フックはローカルクライアント上で呼び出されます。
データは逆方向、つまり、リモートクライアントからサーバーへは同期されません。これを行うには Commands を使用する必要があります。
SyncVars は、NetworkBehaviour から継承するスクリプトの変数です。これはサーバーからクライアントへ同期されます。ゲームオブジェクトがスポーンされたり新しいプレイヤーが進行中のゲームに参加すると、それらから見ることのできるネットワーク化されたオブジェクトの全ての SyncVars の最新の状態が、その新しいオブジェクトやプレイヤーに送信されます。スクリプトのどの変数を同期したいかを特定するために [SyncVar]
のカスタム属性を使用します。
class Player : NetworkBehaviour {
[SyncVar]
int health;
public void TakeDamage(int amount)
{
if (!isServer)
return;
health -= amount;
}
}
SyncVar の状態は、OnStartClient() が呼び出される前にクライアント上のゲームオブジェクトに適用されます。ですから、オブジェクトの状態は、OnStartClient() 内で常に最新の状態に保たれています。
SyncVar は int、string、float などの基本的な型で使用可能です。Vector3 やユーザー定義の構造体などの Unity の型でも使用可能ですが、構造体内のフィールドが変更される場合は、構造体の SyncVar の更新は、インクリメントの変更ではなくモノリシックの更新として送信されます。SyncLists に含まれる 1つの NetworkBehaviour スクリプトには、最多で 32 個の SyncVar を設定できます (後述を参照)。
SyncVar の値が変わると、サーバーは自動的に SyncVar 更新を送信します。そのため、それらが変更された時間や変更に関する情報が送信された時間を追跡する必要はありません。
SyncVars は値を格納しますが、SyncList は値のリストです。SyncList のコンテンツは SyncVar の状態といっしょに最初の状態更新に含まれています。SyncList はそれ自体のコンテンツを同期させるクラスなので、SyncList は SyncVar 属性を必要としません。以下の SyncList が基本的な型として使用可能です。
SyncListString
SyncListFloat
SyncListInt
SyncListUInt
SyncListBool
独自の構造体型のリストを同期するために使用できる SyncListStruct もあります。SyncListStruct を使用するとき、使用する構造体型には、基本型、配列、一般的な Unity 型のメンバーを使うことができます。それらは、複雑なクラスやジェネリックなコンテナを使用することはできません。さらに、これらの構造体では、パブリック変数のみがシリアライズされます。
SyncLists は、リストのコンテンツが変更されたとき、クライアントにそれを知らせる Callback と呼ばれる SyncListChanged デリゲートを持っています。このデリゲートは、発生した操作のタイプや操作を行った項目のインデックスで呼び出されます。
public class MyScript : NetworkBehaviour
{
public struct Buf
{
public int id;
public string name;
public float timer;
};
public class TestBufs : SyncListStruct<Buf> {}
TestBufs m_bufs = new TestBufs();
void BufChanged(Operation op, int itemIndex)
{
Debug.Log("buf changed:" + op);
}
void Start()
{
m_bufs.Callback = BufChanged;
}
}