Serialization adalah proses otomatis mengubah struktur data atau GameObject menyatakan ke dalam format yang dapat disimpan Unity dan reconstruct nanti.
Bagaimana Anda mengatur data dalam proyek Unity Anda mempengaruhi bagaimana menyatukan data tersebut, yang dapat memiliki dampak signifikan pada kinerja proyek Anda. Serialisasi outlines halaman ini dalam Unity dan bagaimana mengoptimalkan proyek Anda untuk itu.
Dokumen ini mencakup topik berikut:
Serializers di Unity dirancang khusus untuk beroperasi secara efisien pada runtime. Karena ini, serialisasi dalam persatuan berperilaku berbeda untuk serialisasi di lingkungan pemrograman lainnya. Serializers dalam pekerjaan Unity langsung pada fields dari Anda C# kelas daripada properti mereka, sehingga ada aturan bahwa bidang Anda harus sesuai untuk menjadi serialisasi. Bagian berikut menguraikan cara menggunakan serialisasi lapangan di Unity.
Untuk menggunakan serialisasi lapangan Anda harus memastikan bahwa lapangan:
List<T>
dari jenis lapangan yang disebutkan di atasNote: Unity tidak mendukung serialisasi jenis multilevel (multidimensional array, array bergerigi, dictionaries, dan tipe kontainer bersarang). Jika Anda ingin serialisasi ini, Anda memiliki dua pilihan:
Untuk menyatukan kelas kustom, Anda harus memastikan kelas:
Ketika Anda menetapkan instance dari kelas yang telah ditentukan oleh UnityEngine.Object
ke lapangan dan Unity menyimpan bidang itu, Unity serializes lapangan sebagai referensi untuk contoh itu. Unity serializes instance itu sendiri secara mandiri, sehingga tidak diduplikasi ketika beberapa bidang ditugaskan ke instance. Tapi untuk kelas kustom yang tidak berasal dari UnityEngine.Object
, Unity mencakup keadaan instance langsung dalam data serialisasi MonoBehaviour atau ScriptableObject yang merujuk pada mereka. Ada dua cara yang bisa terjadi: inline dan oleh [SerializeReference]
.
[SerializeReference]
di lapangan yang merujuk pada kelas. Ini berarti bahwa jika Anda menyimpan referensi ke instance kelas kustom di beberapa bidang yang berbeda, mereka menjadi benda terpisah ketika serialisasi. Kemudian, ketika Unity deserializes bidang, mereka mengandung benda yang berbeda dengan data yang identik.[SerializeReference]
serialization: Jika Anda menentukan [SerializeReference]
, Unity menetapkan objek sebagai referensi yang dikelola. Objek host masih menyimpan objek langsung dalam data serial, tetapi di bagian registry khusus. [SerializeReference]
menambahkan beberapa overhead tetapi mendukung kasus berikut:
[SerializeReference]
, maka mereka menjadi benda terpisah ketika serialisasi.[SerializeReference]
Unity hanya menampilkan bidang yang milik kelas induk. Ketika Unity deserializes instance kelas, seketika kelas induk bukan kelas yang berasal. Note: serialisasi inline lebih efisien, dan Anda harus menggunakannya kecuali jika Anda membutuhkan salah satu fitur yang mendukung [SerializeReference]
. Untuk rincian lengkap tentang cara menggunakan [SerializeReference]
, lihat dokumentasi SerializeReference.
Unity tidak biasanya men serialisasi properti kecuali dalam situasi berikut:
public int MyInt
{
get => m_backing;
private set => m_backing = value;
}
[SerializeField] private int m_backing;
public int MyInt { get; set; }
Kadang-kadang Anda mungkin ingin serialisasi sesuatu yang serializer Unity tidak mendukung (misalnya, Kamus C#). Pendekatan terbaik adalah menerapkan antarmuka ISerializationCallbackReceiver di kelas Anda. Hal ini memungkinkan Anda untuk menerapkan callback yang diinvokasi pada poin kunci selama serialisasi dan deserialisasi:
OnBeforeSerialize()
. Di dalam panggilan ini adalah di mana Anda dapat mengubah data Anda menjadi sesuatu yang saling memahami. Sebagai contoh, untuk serialisasi C# Kamus, salin data dari Kamus ke dalam array kunci dan array nilai.OnBeforeSerialize()
selesai, Unity serialisasi array.OnAfterDeserialize()
. Di dalam panggilan ini adalah di mana Anda dapat mengubah data kembali menjadi bentuk yang nyaman untuk objek dalam memori. Misalnya, gunakan array kunci dan nilai untuk mengenali Kamus C#.Unity menggunakan serialisasi untuk memuat dan menyimpan scenesAdegan berisi lingkungan dan menu permainan Anda. Pikirkan setiap file Adegan unik sebagai tingkat yang unik. Di setiap Adegan, Anda menempatkan lingkungan, hambatan, dan dekorasi, pada dasarnya merancang dan membangun permainan Anda dalam potongan-potongan. More info
Lihat di Glossary, AssetsSetiap media atau data yang dapat digunakan dalam permainan atau proyek Anda. Aset mungkin berasal dari file yang dibuat di luar Unity, seperti model 3D, file audio atau gambar. Anda juga dapat membuat beberapa jenis aset di Unity, seperti Pengontrol Animator, Audio Mixer atau Tekstur Render. More info
Lihat di Glossary, dan AssetBundles ke dan dari memori perangkat Anda. Ini termasuk data yang disimpan dalam objek API scripting Anda sendiri seperti komponen MonoBehaviour dan Login Sitemap.
Banyak fitur di Editor Unity dibangun di atas sistem serialisasi inti. Dua hal untuk sangat menyadari dengan serialisasi adalah Jendela inspektur, dan pemuatan panas.
Jendela Inspektur menunjukkan nilai bidang serialisasi objek yang diperiksa. Ketika Anda mengubah nilai dalam Inspektur, Inspektur memperbarui data serial dan memicu deserialisasi yang memperbarui objek yang diperiksa.
Hal yang sama berlaku untuk objek Unity bawaan, dan objek scripting seperti kelas MonoBehaviour-derived.
Unity tidak menelepon ajang C# properti dan setters ketika Anda melihat atau mengubah nilai di jendela Inspektur; bukan, Unity mengakses bidang backing serialisasi langsung.
Reloading panas adalah di mana Anda membuat atau mengedit 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 sementara Editor terbuka dan menerapkan perilaku skrip segera. Anda tidak perlu me-restart Editor untuk perubahan untuk mengambil efek.
Ketika Anda mengubah dan menyimpan skrip, Reload panas Unity semua data skrip yang dimuat pada waktu. Unity menyimpan semua variabel serializable di semua skrip yang dimuat, kemudian isi ulang skrip dan mengembalikan variabel serial. Hot reloading membuang semua data yang tidak serializable, sehingga Anda tidak akan dapat mengakses data setelahnya.
Ini mempengaruhi semua jendela Editor dan semua MonoBehaviours dalam proyek. Tidak seperti kasus lain dari serialisasi, Unity serializes bidang pribadi secara default ketika reloading, bahkan jika mereka tidak memiliki atribut 'SerializeField'.
Ketika skrip reload Unity:
[SerializeField]
. Kadang-kadang, Anda perlu mencegah Unity dari variabel pribadi restoring, misalnya, jika Anda ingin referensi untuk menjadi null setelah reloading dari script. Dalam kasus ini, gunakan atribut [field: NonSerialized]
.A PrefabJenis aset yang memungkinkan Anda untuk menyimpan GameObject lengkap dengan komponen dan properti. Prefab bertindak sebagai template dari mana Anda dapat membuat instance objek baru di tempat kejadian. More info
Lihat di Glossary adalah data serial dari satu atau lebih GameObjectsObjek 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 atau componentsBagian fungsional dari GameObject. GameObject dapat mengandung sejumlah komponen. Unity memiliki banyak komponen built-in, dan Anda dapat membuat Anda sendiri dengan menulis skrip yang berwarisi dari MonoBehaviour. More info
Lihat di Glossary. Contoh Prefab mengandung referensi untuk kedua sumber Prefab dan daftar modifikasi untuk itu. Modifikasi adalah apa yang perlu dilakukan Unity untuk sumber Prefab untuk membuat instance Prefab tertentu.
Contoh Prefab hanya ada saat Anda mengedit proyek Anda di Editor Unity. Editor Unity mengikutkan GameObject dari dua set data serialisasinya: sumber Prefab dan modifikasi instance Prefab.
Ketika Anda memanggil Instantiate
pada apa pun yang ada di tempat kejadian, seperti Prefab atau GameObject:
UnityEngine.Object
.UnityEngine.Objects
lain itu referensi. Ini memeriksa semua referensi UnityEngine.Objects
untuk melihat apakah mereka bagian dari data Unity instaniates. Jika titik referensi untuk sesuatu yang eksternal, seperti Tekstur, Unity menyimpan referensi itu. Jika titik referensi untuk sesuatu yang internal, seperti anak GameObject, Unity patch referensi ke salinan yang sesuai. EditorUtility.UnloadUnusedAssetsImmediate
adalah kolektor sampah Unity asli dan memiliki tujuan yang berbeda untuk kolektor sampah C# standar. Ini berjalan setelah Anda memuat adegan dan memeriksa objek (seperti Tekstur) yang tidak lagi referensi dan membongkar mereka dengan aman. Pengumpul sampah Unity asli menjalankan serializer dalam variasi objek mana melaporkan semua referensi ke UnityEngine.Objects
eksternal. Ini adalah bagaimana Tekstur yang digunakan satu adegan, bongkar kolektor garbage di depan.
Kebanyakan serialisasi terjadi di Editor, sedangkan deserialization adalah fokus pada runtime. Unity serializes beberapa fitur hanya di Editor, sementara itu dapat serialisasi fitur lain di kedua Editor dan pada runtime:
Feature | Editor | Runtime |
---|---|---|
Assets in Binary Format | Baca/ tulis didukung | Baca didukung |
Assets in YAML format | Baca/ tulis didukung | Tidak didukung |
Saving scenes, prefabs and other assets | Didukung, kecuali dalam mode Bermain | Tidak didukung |
Serialization of individual objects with JsonUtility | Baca/ tulis dukungan dengan JsonUtility. Support untuk jenis objek tambahan dengan EditorJsonUtility |
Baca/ tulis dukungan dengan JsonUtility |
SerializeReference | Supported | Supported |
ISerializationCallbackReceiver | Supported | Supported |
FormerlySerializedAs | Supported | Tidak didukung |
Objek dapat memiliki bidang tambahan yang hanya serialisasi Editor, seperti ketika Anda menyatakan bidang dalam UNITY_ EDITOR simbol scripting:
public class SerializeRules : MonoBehaviour
{
#if UNITY_EDITOR
public int m_intEditorOnly;
#endif
}
Dalam contoh di atas, lapangan m_intEditorOnly
hanya serialisasi dalam editor dan tidak termasuk dalam build. Hal ini memungkinkan Anda untuk menyimpan memori dengan data yang hanya diperlukan dalam Editor dari build Anda. Setiap kode yang menggunakan bidang itu juga perlu dikompilasi secara kondisional, misalnya dalam blok #if UNITY_EDITOR, sehingga kelas dapat mengkompilasi pada waktu membangun.
Editor tidak mendukung benda-benda dengan bidang yang bersatu hanya serialisasi pada runtime, (misalnya, ketika Anda menyatakan bidang di dalam UNITY_STANDALONE directive).
serialisasi script dapat menyebabkan kesalahan. Perbaiki beberapa ini tercantum di bawah ini.
Login API seperti GameObject.Find
di dalam konstruktor MonoBehaviour atau initializer lapangan memicu kesalahan ini.
Untuk memperbaiki ini, lakukan panggilan ke API Scripting di MonoBehaviour.Start
bukan dalam konstruktor.
Memanggil Scripting API seperti GameObject. Cari dari dalam penyusunan kelas ditandai dengan System.Serializable
memicu kesalahan ini.
Untuk memperbaiki ini, edit kode Anda sehingga tidak membuat panggilan API Scripting di setiap konstruktor untuk objek serial.
Pembatasan di atas mempengaruhi sebagian besar API Scripting. Hanya beberapa bagian dari API skrip Unity dibebaskan dan Anda dapat menyebutnya dari mana saja:
Debug.Log
Mathf
fungsiVector3
dan Quaternion
Untuk mengurangi risiko kesalahan selama serialisasi, hanya memanggil metode API yang mandiri dan tidak perlu mendapatkan atau mengatur data di Unity sendiri, kecuali tidak ada alternatif.
Anda dapat mengatur data Anda untuk memastikan Anda mendapatkan penggunaan serialisasi Unity yang optimal.
UnityEngine.Object
. Kelas-kelas ini terpisah; mereka hanya referensi satu sama lain dan mereka tidak malu konten.