Sinchronisasi negara
visibilitas jaringan

Sinkronisasi Negara Tingkat Lanjut

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.

Custom Serialization Functions

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.

Serialization Flow

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.

Sinchronisasi negara
visibilitas jaringan