Important: UNet adalah solusi yang diuraikan, dan Solusi Multiplayer baru dan NetworkingSistem Unity yang memungkinkan game multiplayer di jaringan komputer. More info Lihat di Glossary (Netcode untuk GameObjects) sedang berkembang. Untuk informasi lebih lanjut dan langkah selanjutnya melihat informasi di . |
Dalam kebanyakan kasus, penggunaan SyncVars cukup untuk permainan Anda scriptsSepotong kode yang memungkinkan Anda untuk membuat Komponen Anda sendiri, memicu peristiwa permainan, memodifikasi sifat komponen dari waktu ke waktu dan menanggapi input pengguna dengan cara apa pun yang Anda sukai. More info
Lihat di Glossary untuk serialisasi keadaan mereka kepada klien. Namun dalam beberapa kasus Anda mungkin memerlukan kode serialisasi yang lebih kompleks. Halaman ini hanya relevan untuk pengembang canggih yang membutuhkan solusi sinkronisasi yang disesuaikan yang melampaui fitur Sinkronisasi normal Unity.
Untuk melakukan serialisasi kustom Anda sendiri, Anda dapat menerapkan fungsi virtual pada NetworkBehaviour untuk digunakan untuk serialisasi SyncVar. Fungsi ini adalah:
public virtual bool OnSerialize(NetworkWriter writer, bool initialState);
public virtual void OnDeSerialize(NetworkReader reader, bool initialState);
Gunakan bendera initialState
untuk membedakan antara pertama kalinya GameObjectObjek mendasar dalam adegan Unity, yang dapat mewakili karakter, props, pemandangan, kamera, waypoints, dan banyak lagi. Fungsi GameObject didefinisikan oleh Komponen yang melekat padanya. More info
Lihat di Glossary serialisasi dan ketika pembaruan inkremental dapat dikirim. Pertama kali GameObject dikirim ke klien, itu harus mencakup snapshot negara penuh, tetapi pembaruan berikutnya dapat menghemat bandwidth dengan hanya perubahan inkremental. Perhatikan bahwa fungsi hook SyncVar tidak disebut ketika initialState
benar; mereka hanya disebut untuk pembaruan inkremental.
Jika kelas memiliki SyncVars, maka implementasi fungsi ini ditambahkan secara otomatis ke kelas, berarti bahwa kelas yang memiliki SyncVars juga tidak dapat memiliki fungsi serialisasi khusus.
Fungsi OnSerialize
harus kembali benar untuk menunjukkan bahwa pembaruan harus dikirim. Jika kembali benar, mata kotor untuk skrip itu diatur ke nol. Jika kembali palsu, mata kotor tidak berubah. Ini memungkinkan beberapa perubahan pada skrip untuk terakumulasi dari waktu ke waktu dan dikirim ketika sistem siap, bukan setiap bingkai.
GameObjects dengan komponen Identitas Jaringan terpasang dapat memiliki beberapa skrip yang berasal dari NetworkBehaviour
. Aliran untuk serialisasi GameObjects ini adalah:
Di server:
Setiap NetworkBehaviour
memiliki masker kotor. Masker ini tersedia dalam OnSerialize
sebagai syncVarDirtyBits
Setiap SyncVar dalam script NetworkBehaviour
ditugaskan sedikit dalam masker kotor.
Mengubah nilai SyncVars menyebabkan bit untuk SyncVar untuk diatur dalam masker kotor
Atau, memanggil SetDirtyBit()
menulis langsung ke masker kotor
NetworkIdentityKomponen Jaringan yang memungkinkan Anda untuk menetapkan identitas ke GameObject Anda untuk jaringan untuk mengenalinya sebagai GameObject Pemain Lokal atau Server Hanya GameObject. More info
Lihat di Glossary GameObjects are checked on the server as part of it’s update loop
Jika ada NetworkBehaviours
pada NetworkIdentity
kotor, maka paket UpdateVars
diciptakan untuk GameObject
Paket UpdateVars
diisi dengan memanggil OnSerialize
pada setiap NetworkBehaviour
pada GameObject
NetworkBehaviours
yang tidak kotor menulis nol ke paket untuk bit kotor mereka
NetworkBehaviours
yang kotor menulis masker kotor mereka, maka nilai-nilai untuk SyncVars yang telah berubah
Jika OnSerialize
kembali benar untuk NetworkBehaviour
, masker kotor diatur untuk NetworkBehaviour
, sehingga tidak mengirim lagi sampai perubahan nilainya.
Paket UpdateVars
dikirim ke klien siap yang mengamati GameObject
Di klien:
UpdateVars packet
diterima untuk GameObject
Fungsi OnDeserialize
disebut untuk setiap skrip NetworkBehaviour
pada GameObject
Setiap skrip NetworkBehaviour
pada GameObject membaca masker kotor.
Jika masker kotor untuk NetworkBehaviour
adalah nol, fungsi OnDeserialize
kembali tanpa membaca lebih
Jika masker kotor adalah nilai non-zero, maka fungsi OnDeserialize
membaca nilai-nilai untuk SyncVars yang sesuai dengan bit kotor yang ditetapkan
Jika ada fungsi hook SyncVar, mereka diinjak dengan nilai yang dibaca dari aliran.
Jadi untuk script ini:
public class data : NetworkBehaviour
{
[SyncVar]
public int int1 = 66;
[SyncVar]
public int int2 = 23487;
[SyncVar]
public string MyString = "Example string";
}
Sampel kode berikut menunjukkan fungsi OnSerialize
yang dihasilkan:
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
{
if (forceAll)
{
// The first time a GameObject is sent to a client, send all the data (and no dirty bits)
writer.WritePackedUInt32((uint)this.int1);
writer.WritePackedUInt32((uint)this.int2);
writer.Write(this.MyString);
return true;
}
bool wroteSyncVar = false;
if ((base.get_syncVarDirtyBits() & 1u) != 0u)
{
if (!wroteSyncVar)
{
// Write dirty bits if this is the first SyncVar written
writer.WritePackedUInt32(base.get_syncVarDirtyBits());
wroteSyncVar = true;
}
writer.WritePackedUInt32((uint)this.int1);
}
if ((base.get_syncVarDirtyBits() & 2u) != 0u)
{
if (!wroteSyncVar)
{
// Write dirty bits if this is the first SyncVar written
writer.WritePackedUInt32(base.get_syncVarDirtyBits());
wroteSyncVar = true;
}
writer.WritePackedUInt32((uint)this.int2);
}
if ((base.get_syncVarDirtyBits() & 4u) != 0u)
{
if (!wroteSyncVar)
{
// Write dirty bits if this is the first SyncVar written
writer.WritePackedUInt32(base.get_syncVarDirtyBits());
wroteSyncVar = true;
}
writer.Write(this.MyString);
}
if (!wroteSyncVar)
{
// Write zero dirty bits if no SyncVars were written
writer.WritePackedUInt32(0);
}
return wroteSyncVar;
}
Sampel kode berikut menunjukkan fungsi OnDeserialize
:
public override void OnDeserialize(NetworkReader reader, bool initialState)
{
if (initialState)
{
this.int1 = (int)reader.ReadPackedUInt32();
this.int2 = (int)reader.ReadPackedUInt32();
this.MyString = reader.ReadString();
return;
}
int num = (int)reader.ReadPackedUInt32();
if ((num & 1) != 0)
{
this.int1 = (int)reader.ReadPackedUInt32();
}
if ((num & 2) != 0)
{
this.int2 = (int)reader.ReadPackedUInt32();
}
if ((num & 4) != 0)
{
this.MyString = reader.ReadString();
}
}
Jika seorang NetworkBehaviour
memiliki kelas dasar yang juga memiliki fungsi serialisasi, fungsi kelas dasar juga harus disebut.
Perhatikan bahwa paket UpdateVar
yang dibuat untuk pembaruan state GameObject dapat diatur dalam buffer sebelum dikirim ke klien, sehingga paket lapisan transportasi tunggal dapat berisi pembaruan untuk beberapa GameObjects.