狀態同步
狀態同步是從伺服器端到遠端客戶端中來完成。自從和伺服器端共用場景時,本地客戶端不會有資料序列化。任何資料序列化給本地客戶端是多餘的。然而 SyncVar 會在本地客戶端被呼叫時掛勾上去。
資料不會從遠端客戶端同步到伺服器端,那是 命令(Command) 的工作。
同步變數
同步變數(SyncVar) 是從伺服器同步到客戶端, NetworkBehaviour 腳本中的成員變數。當物件被產生(Spawn)或是新玩家在半途中加入遊戲時,它們身上可見的的網路物件會收到所有同步變數的最新狀態。藉由使用 [SyncVar] 自訂標籤,可讓成員變數要轉變為同步變數:
class Player : NetworkBehaviour
{
[SyncVar]
int health;
public void TakeDamage(int amount)
{
if (!isServer)
return;
health -= amount;
}
}
同步變數的狀態會在 OnStartClient() 被呼叫之前套用到客戶端上的物件,所以物件的狀態被保證會在 OnStartClient() 之中是最新的狀態。
同步變數可以是整數、字串或浮點數等基本型別。它也可以像是 Vector3 等等的 Unity 內建型別或是使用者定義結構,但是結構類型的同步變數更新時,是以單體方式來送出,而並非結構內的欄位更新時,遞增去做更新。一個 NetworkBehaviour 腳本最多可以擁有 32 個同步變數,這包含了同步陣列。
當同步變數在伺服器端被改變時,更新會自動的被送出。並不需要為同步變數去執行任何手動的更變標記(Dirtying)。
同步陣列
同步陣列(SyncList) 類似同步變數,但是是以值得集合取代獨立的值。同步陣列的內容包含了同步變數的初始狀態更新。同步陣列不需要 SyncVar 標籤,它們是特製的類別。這些是內建設定給基本型別的同步陣列類型:
- SyncListString
- SyncListFloat
- SyncListInt
- SyncListUInt
- SyncListBool
也有可被用在使用者定義結構的 SyncListStruct 類別。使用自訂結構且繼承 SyncListStruct 類別的成員可以包含基本型別、陣列和常見的 Unity 型別。它們不可以包含複雜的類別或是泛型容器。
同步陣列有個以 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(SyncListStruct<Buf>.Operation op, int itemIndex)
{
Debug.Log("buf changed:" + op);
}
void Start()
{
m_bufs.Callback = BufChanged;
}
}