Saat mengembangkan game multipemain dengan PUN2, akan ada kasus di mana pengiriman tipe khusus seperti struktur atau kelas yang ditentukan pengguna melalui RPC dan Acara, dll. Namun, mengirimkan tipe khusus ini secara langsung ke jaringan tidak diperbolehkan di PUN2. Sebaliknya, PUN2 menyediakan metode pendaftaran tipe khusus sebagai solusi.
Untuk menggunakan metode pendaftaran tipe kustom PUN2, tipe kustom harus diserialkan ke dalam array byte. Dalam banyak kasus, serialisasi byte dilakukan menggunakan Binary Formatter. Namun, Binary Formatter menghasilkan byte tambahan dalam jumlah besar, yang akan mengganggu lalu lintas untuk game intensif jaringan dan memberikan pengalaman buruk bagi pengguna seluler yang tidak dapat menggunakan koneksi WIFI gratis. Selain itu, Binary Formatter tidak dapat membuat serial Vector2, Vector3, Quaternion, dan lain-lain dari Unity.
Arsip ini menyediakan metode pendaftaran tipe khusus dengan skrip dan membandingkan perbedaannya dengan metode serialisasi lainnya.
Struktur yang diberikan akan diserialkan dengan Binary Formatter dan ukurannya akan diukur oleh Marshal. Perhatikan bahwa objek Unity seperti Vector3, Quaternion, dan lain-lain tidak disertakan karena objek tersebut tidak dapat diserialkan oleh Binary Formatter.
public struct TestStruct
{
public int int_1 ;
public int int_2 ;
public string string_1 ;
public float float_1 ;
public float float_2 ;
}
TestStruct testStruct = new TestStruct
{
int_1 = 30 ,
int_2 = 71 ,
string_1 = " ABC가나다 " ,
float_1 = 0.162f ,
float_2 = 62f ,
} ;
Serialisasi struktur dan pengukuran ukurannya adalah sebagai berikut:
public void BinaryFormatterSerialize ( TestStruct testStruct )
{
byte [ ] bytes ;
MemoryStream memoryStream = new MemoryStream ( ) ;
BinaryFormatter binaryFormatter = new BinaryFormatter ( ) ;
binaryFormatter . Serialize ( memoryStream , testStruct ) ;
memoryStream . Close ( ) ;
bytes = memoryStream . ToArray ( ) ;
Debug . Log ( string . Format ( " Bianary Formatter Serialized Size : {0} bytes " , bytes . Length ) ) ;
}
public void CheckSize ( TestStruct testStruct )
{
Debug . Log ( string . Format ( " Original Size : {0} bytes " , Marshal . SizeOf ( testStruct ) ) ) ;
Debug . Log ( JsonUtility . ToJson ( testStruct , true ) ) ;
}
Hasilnya adalah sebagai berikut:
ukuran (byte) | |
---|---|
Asli | 24 byte |
Pemformat Biner | 199 byte |
Ukuran teoritis dari struktur yang diberikan adalah 24 byte. Ketika struktur yang diberikan diserialkan dengan Binary Formatter, ukurannya adalah 199 byte yang 8 kali lebih besar dari ukuran teoritis. Hal ini dapat menyebabkan overhead lalu lintas saat membuat serial dan mengirimkannya ke jaringan.
Struktur yang diberikan di atas akan diserialkan dengan JsonUtility dan dicakup menjadi byte. Serialisasi strukturnya adalah sebagai berikut:
public void JsonSerialize ( TestStruct testStruct )
{
byte [ ] bytes = Encoding . UTF8 . GetBytes ( JsonUtility . ToJson ( testStruct ) ) ;
Debug . Log ( string . Format ( " JsonUtility Serialized Size : {0} bytes " , bytes . Length ) ) ;
}
Hasilnya adalah sebagai berikut:
ukuran (byte) | |
---|---|
Asli | 24 byte |
JsonUtility & konversi byte | 94 byte |
Ketika struktur yang diberikan diserialkan dengan JsonUtility dan dikonversi ke byte, ukurannya adalah 94 byte yaitu sekitar 4 kali lebih besar dari ukuran teoritis. Ukuran ini dapat diperkecil dengan memperpendek nama variabelnya. Misalnya nama variabel diubah seperti gambar di bawah ini, maka hasilnya adalah sebagai berikut.
public struct TestStruct
{
public int a ;
public int b ;
public string c ;
public float d ;
public float e ;
}
TestStruct testStruct = new TestStruct
{
a = 30 ,
b = 71 ,
c = " ABC가나다 " ,
d = 0.162f ,
e = 62f ,
} ;
ukuran (byte) | |
---|---|
Asli | 24 byte |
JsonUtility & konversi byte | 67 byte |
Ukuran byte dikurangi dari 94 byte menjadi 67 byte. Namun, ini masih lebih besar dari ukuran teoritis yaitu 24 byte.
Arsip ini memperkenalkan serializer khusus yang dapat membuat serial tipe kustom seperti struktur atau kelas yang ditentukan pengguna. Serializer ini dapat memberikan ukuran yang mendekati ukuran teoritis. Jenis dan ukuran yang dapat diserialkan adalah sebagai berikut:
Jenis | Ukuran (byte) |
---|---|
byte | 1 byte |
byte[] | 4 + (1 * Panjang) byte |
bodoh | 1 byte |
bodoh[] | 4 + (1 * Panjang) byte |
ke dalam | 4 byte |
ke dalam[] | 4 + (4 * Panjang) byte |
mengambang | 4 byte |
mengambang[] | 4 + (4 * Panjang) byte |
Vektor2 | 8 byte |
Vektor2[] | 4 + (8 * Panjang) byte |
Vektor3 | 12 byte |
Vektor3[] | 4 + (12 * Panjang) byte |
Angka empat | 16 byte |
Angka empat[] | 4 + (16 * Panjang) byte |
rangkaian | 4 + α (Pengkodean UTF8) byte |
rangkaian[] | 4 + ((4 + α) * Panjang) byte |
Pertama-tama deklarasikan menggunakan MSLIMA.Serializer di atas.
using MSLIMA.Serializer;
Kemudian, misalkan strukturnya diberikan sebagai berikut:
public struct TestStruct
{
public int int_1 ;
public int int_2 ;
public float float_1 ;
public bool bool_1 ;
public string string_1 ;
public Vector3 vector3_1 ;
public Vector3 vector3_2 ;
public Quaternion quaternion_1 ;
}
TestStruct testStruct = new TestStruct
{
int_1 = 30 ,
int_2 = 71 ,
float_1 = 0.162f ,
bool_1 = true ,
string_1 = " ABC가나다 " ,
vector3_1 = new Vector3 ( - 23f , 62f , 26f ) ,
vector3_2 = new Vector3 ( 1f , 7f , - 15f ) ,
quaternion_1 = Quaternion . Euler ( 35f , 0f , 15f )
} ;
Pertama, buat metode statis dengan nama "Serialize" dan "Deserialize" di dalam tipe kustom . Metode "Serialize" memiliki satu parameter dengan tipe objek dan tipe pengembalian dengan tipe byte[]. Metode "Deserialize" memiliki satu parameter dengan tipe byte[] dan tipe objek yang dikembalikan.
Perhatikan bahwa nama metode, parameter, dan tipe pengembalian harus sama seperti yang dijelaskan. Selain itu, metode ini harus bersifat statis.
public static byte [ ] Serialize ( object customObject )
{
}
public static object Deserialize ( byte [ ] bytes )
{
}
Kedua, masukkan customObject ke tipe khusus, deklarasikan array byte dalam metode "Serialize".
public static byte [ ] Serialize ( object customObject )
{
TestStruct o = ( TestStruct ) customObject ;
byte [ ] bytes = new byte [ 0 ] ;
}
Sekarang, gunakan metode Serializer untuk membuat serialisasi bidang yang diinginkan dan akhirnya mengembalikan byte. Perhatikan bahwa array byte diteruskan dengan kata kunci ref.
public static byte [ ] Serialize ( object customObject )
{
.. .
Serializer . Serialize ( o . int_1 , ref bytes ) ;
Serializer . Serialize ( o . int_2 , ref bytes ) ;
Serializer . Serialize ( o . float_1 , ref bytes ) ;
Serializer . Serialize ( o . bool_1 , ref bytes ) ;
Serializer . Serialize ( o . string_1 , ref bytes ) ;
Serializer . Serialize ( o . vector3_1 , ref bytes ) ;
Serializer . Serialize ( o . vector3_2 , ref bytes ) ;
Serializer . Serialize ( o . quaternion_1 , ref bytes ) ;
return bytes ;
}
Ketiga, buat tipe kustom baru dalam metode "Deserialize" dan deklarasikan variabel offset dengan tipe int dan inisialisasi dengan 0.
public static object Deserialize ( byte [ ] bytes )
{
TestStruct o = new TestStruct ( ) ;
int offset = 0 ;
}
Sekarang, gunakan metode deserialize Serializer untuk membatalkan serialisasi bidang yang diserialkan di atas. Offset diteruskan dengan kata kunci ref dan mengembalikan tipe khusus yang dibuat di atas.
Perhatikan bahwa urutan deserialisasi harus sama dengan urutan serialisasi.
public static object Deserialize ( byte [ ] bytes )
{
.. .
o . int_1 = Serializer . DeserializeInt ( bytes , ref offset ) ;
o . int_2 = Serializer . DeserializeInt ( bytes , ref offset ) ;
o . float_1 = Serializer . DeserializeInt ( bytes , ref offset ) ;
o . bool_1 = Serializer . DeserializeBool ( bytes , ref offset ) ;
o . string_1 = Serializer . DeserializeString ( bytes , ref offset ) ;
o . vector3_1 = Serializer . DeserializeVector3 ( bytes , ref offset ) ;
o . vector3_2 = Serializer . DeserializeVector3 ( bytes , ref offset ) ;
o . quaternion_1 = Serializer . DeserializeQuaternion ( bytes , ref offset ) ;
return o ;
}
Terakhir, tipe kustom harus didaftarkan ke PUN2. Panggil metode yang dijelaskan di bawah ini satu kali untuk mendaftarkan tipe kustom. Jika perlu mendaftarkan beberapa tipe khusus, kode byte harus berbeda. Cukup dicapai dengan mengubah alfabet parameter dalam metode.
Serializer . RegisterCustomType < TestStruct > ( ( byte ) 'A' ) ;
Hasil serialisasi struktur yang diberikan adalah sebagai berikut:
ukuran (byte) | |
---|---|
Asli | 64 byte |
Serialisasi Khusus | 69 byte |
Ukuran teoritisnya adalah 64 byte sedangkan ukuran serial sebenarnya adalah 69 byte. Perbedaan 5 byte disebabkan oleh string, yang ukurannya dapat bervariasi berdasarkan panjangnya. Hasilnya bisa diterima.
Serializer khusus menyediakan ukuran yang lebih kecil daripada serialisasi Binary Formatter atau JsonUtility. Namun, ada keterbatasan yang mungkin menyulitkan untuk menggunakan semua metode serialisasi untuk setiap tipe khusus yang seharusnya diserialkan dan tidak mendukung tipe bersarang. Namun demikian, jika membuat serial tipe kustom sederhana dengan tipe primitif dan sering mengirimkannya ke jaringan, serializer kustom ini akan membantu.
Tambahkan cakupan registri ini.
"scopedRegistries" : [
{
"name" : " MS-LIMA " ,
"url" : " https://package.openupm.com " ,
"scopes" : [
" com.ms-lima "
]
}
]