Menjalankan Kode Script Editor di Launch
serialisasi internal

Script serialization

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:

Sitemap Peraturan serialisasi Serialization rules

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:

  • Adalah publik, atau memiliki atribut Serial attribute
  • tidak statis
  • tidak surut
  • tidak membaca
  • Memiliki tipe lapangan yang dapat serialisasi:
    • Jenis data primitif (int, float, ganda, bool, string, dll)
    • Jenis Enum (32 bit atau lebih kecil)
    • Penyangga ukuran tetap
    • Jenis bawaan unity, misalnya vektor2, vektor3, Rect, Matrix4x4, Warna, AnimasiCurve
    • Struktur kustom dengan atribut Serializable
    • Indeks ke objek yang berasal dari Login Sitemap
    • Kelas kustom dengan atribut Serializable. (Lihat Serialisasi kelas kustom).
    • Berbagai tipe lapangan yang disebutkan di atas
    • A List<T> dari jenis lapangan yang disebutkan di atas

Note: Unity tidak mendukung serialisasi jenis multilevel (multidimensional array, array bergerigi, dictionaries, dan tipe kontainer bersarang). Jika Anda ingin serialisasi ini, Anda memiliki dua pilihan:

Sitemap Serialisasi kelas kustom Serialization of custom classes

Untuk menyatukan kelas kustom, Anda harus memastikan kelas:

  • Memiliki atribut Serial attribute
  • tidak statis.

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].

  • Inline serialization: Secara default, Unity serialisasi kelas kustom sesuai nilai ketika Anda tidak menentukan [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:

  • Lapangan dapat di null. serialisasi inline tidak dapat mewakili null, bukan, itu menggantikan null dengan objek inline yang memiliki bidang yang tidak ditentukan.
  • Beberapa referensi ke objek yang sama. Jika Anda menyimpan referensi ke instance kelas kustom di beberapa bidang yang berbeda tanpa menggunakan [SerializeReference], maka mereka menjadi benda terpisah ketika serialisasi.
  • Grafik dan data siklik (misalnya, objek yang memiliki referensi kembali ke dirinya sendiri). serialisasi kelas Inline tidak mendukung null atau referensi bersama, sehingga setiap siklus data dapat menyebabkan hasil yang tidak terduga, seperti perilaku InspectorJendela Unity yang menampilkan informasi tentang Pengaturan GameObject yang dipilih saat ini, aset atau proyek, memungkinkan Anda untuk memeriksa dan mengedit nilai. More info
    Lihat di Glossary
    aneh, kesalahan konsol atau loop tak terbatas.
  • Polimorfisme. Jika Anda membuat kelas yang berasal dari kelas induk dan menetapkannya ke lapangan yang menggunakan kelas induk sebagai jenisnya, tanpa [SerializeReference] Unity hanya menampilkan bidang yang milik kelas induk. Ketika Unity deserializes instance kelas, seketika kelas induk bukan kelas yang berasal.
  • Ketika struktur data membutuhkan pengenal yang stabil untuk menunjuk ke objek tertentu tanpa mengeras posisi array objek atau mencari seluruh array. SitemapSerialisasiUtility.SetManagedReferenceIdForObject.

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.

Serialisasi properti

Unity tidak biasanya men serialisasi properti kecuali dalam situasi berikut:

  • Jika properti memiliki bidang backing eksplisit, Unity mendemonstrasikannya sesuai dengan aturan serialisasi biasa. Contoh:
public int MyInt
{
get => m_backing;
private set => m_backing = value;
}
[SerializeField] private int m_backing;
  • Unity serializes properti dengan bidang autogenerasi selama reloading panas saja.

    public int MyInt { get; set; }

    Jika Anda tidak ingin menyatukan properti dengan bidang autogenerasi, gunakan atribut [bidang: NonSerialized].

Sitemap serialisasi kustom Custom serialization

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:

  1. Ketika sebuah objek adalah tentang menjadi serialisasi, Unity memanggil callback 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.
  2. Setelah callback OnBeforeSerialize() selesai, Unity serialisasi array.
  3. Kemudian, ketika objek dinonaktifkan, Unity memanggil callback 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#.

Sitemap Bagaimana Unity menggunakan serialisasi How Unity uses serialization

Hemat dan pemuatan

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

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

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:

  1. Unity serializes dan menyimpan semua variabel di semua script yang dimuat.
  2. Unity mengembalikan mereka dengan nilai-nilai pra-serialisasi mereka:
    • Unity mengembalikan semua variabel - termasuk variabel pribadi - yang memenuhi persyaratan untuk serialisasi, bahkan jika variabel tidak memiliki atribut [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].
    • Unity tidak pernah mengembalikan variabel statis, sehingga tidak menggunakan variabel statis untuk negara-negara yang perlu Anda simpan setelah Reload Unity script karena proses reloading akan membuangnya.
    %

Prefabs

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.

Instantiation

Ketika Anda memanggil Instantiate pada apa pun yang ada di tempat kejadian, seperti Prefab atau GameObject:

  1. Unity serializes itu. Ini terjadi baik pada runtime dan di Editor. Unity dapat serialisasi segala sesuatu yang berasal dari UnityEngine.Object.
  2. Unity menciptakan GameObject baru dan merusak data ke GameObject baru.
  3. Unity menjalankan kode serialisasi yang sama dalam varian yang berbeda untuk melaporkan bahwa 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.

Unloading aset yang tidak digunakan

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.

Perbedaan antara serialisasi Editor dan runtime

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).

Sitemap Kesalahan serialisasi Script Script serialization errors

serialisasi script dapat menyebabkan kesalahan. Perbaiki beberapa ini tercantum di bawah ini.

“Find tidak diperbolehkan untuk disebut dari konstruktor MonoBehaviour (atau premiizer lapangan instance), panggilan di Awake atau Start. Sitemap

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.

“Find tidak diperbolehkan untuk disebut selama serialisasi, menyebutnya dari Awake atau Start. Sitemap

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.

API Reference

Pembatasan di atas mempengaruhi sebagian besar API Scripting. Hanya beberapa bagian dari API skrip Unity dibebaskan dan Anda dapat menyebutnya dari mana saja:

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.

Sitemap Praktik terbaik Serialization best practice

Anda dapat mengatur data Anda untuk memastikan Anda mendapatkan penggunaan serialisasi Unity yang optimal.

  • Bertujuan memiliki serialisasi satu Unity dari data yang paling kecil. Tujuan dari ini bukan untuk menghemat ruang pada hard drive komputer Anda, tetapi untuk memastikan bahwa Anda dapat mempertahankan kompatibilitas mundur dengan versi proyek sebelumnya. Kecocokan kembali dapat menjadi lebih sulit kemudian dalam pengembangan jika Anda bekerja dengan set besar data serial.
  • Jangan pernah memiliki data duplikat Unity atau data cache. Hal ini menyebabkan masalah yang signifikan untuk kompatibilitas mundur: itu membawa risiko kesalahan yang tinggi karena data dapat keluar dari sinkronisasi.
  • Hindari struktur berulang di mana Anda merujuk kelas lain. Tata letak struktur serialisasi selalu perlu sama; independen data dan hanya tergantung pada apa yang terpapar dalam skrip. Satu-satunya cara untuk merujuk kelas lain adalah melalui kelas yang berasal dari UnityEngine.Object. Kelas-kelas ini terpisah; mereka hanya referensi satu sama lain dan mereka tidak malu konten.
Menjalankan Kode Script Editor di Launch
serialisasi internal