Unity のシリアライザーは、特にランタイムで効率的に動作するように設計されています。そのため、Unity のシリアル化は、他のプログラミング環境のシリアル化とは異なる挙動をします。Unity のシリアライザーは、プロパティではなく C# クラスのフィールドで直接機能します。そのため、Unity は特定の条件を満たす場合にのみフィールドをシリアル化します。以下のセクションでは、Unity でフィールドのシリアル化を行う方法の概要を説明します。
フィールドシリアライゼーションを使用するには、フィールドが以下の状態であることを確認します。
public または SerializeField 属性を持つこと。
private フィールドがシリアル化されます。詳しくはホットリロードを参照してください。static でないこと。const でないこと。readonly でないこと。List<T> であること。ノート: Unity は、マルチレベルの型 (多次元配列、ジャグ配列、辞書、ネストされたコンテナタイプ) のシリアル化をサポートしていません。これらをシリアル化するには 2 つのオプションがあります。
Unity がカスタムクラスをシリアライズするためには、クラスが以下の状態であることが必要です。
UnityEngine.Object から派生したクラスのインスタンスをフィールドに割り当て、そのフィールドを保存する場合、Unity はフィールドをシリアル化してそのインスタンスへの参照にします。Unity はそのインスタンス自体を個々にシリアル化します。そのため、インスタンスに複数のフィールドが割り当てられても重複しません。しかし、UnityEngine.Object から派生しないカスタムクラスの場合、Unity はインスタンスの状態を、それらを参照する MonoBehaviour や ScriptableObject のシリアル化されたデータに直接加えます。これには、インラインと [SerializeReference] の 2 つの方法があります。
[SerializeReference] を指定しない場合、Unity はカスタムクラスを値によってインラインでシリアル化します。つまり、カスタムクラスのインスタンスへの参照を複数の異なるフィールドに保存する場合、それらはシリアル化されると別々のオブジェクトになります。フィールドをデシリアライズすると、それらは同一のデータを持つ異なる別個のオブジェクトを含みます。[SerializeReference] でシリアル化:[SerializeReference] を指定する場合、Unity はオブジェクトをマネージ参照として確立します。ホストオブジェクトは、オブジェクトをそのシリアル化されたデータに直接保存しますが、専用のレジストリセクションに格納します。
[SerializeReference] は若干のオーバーヘッドを追加しますが、以下のケースをサポートします。
[SerializeReference] を使用せずに、カスタムクラスのインスタンスへの参照を複数の異なるフィールドに格納する場合、それらはシリアル化すると別々のオブジェクトになります。[SerializeReference] なしに、Unity は親クラスに属するフィールドのみをシリアル化します。Unity はクラスインスタンスをデシリアライズするとき、派生クラスではなく、親クラスをインスタンス化します。
ノート: インラインのシリアル化はより効率的なので、[SerializeReference] がサポートする機能の 1 つを特に必要としない限り、インラインのシリアル化を使用することをお勧めします。[SerializeReference] の使用方法の詳細は、SerializeReference のドキュメントを参照してください。
Unity では、以下のような場合を除き、通常プロパティをシリアル化することはありません。
public int MyInt
{
get => m_backing;
private set => m_backing = value;
}
[SerializeField] private int m_backing;
public int MyInt { get; set; }
自動生成されたフィールドを持つプロパティを Unity にシリアル化させたくない場合は、[field: NonSerialized] 属性を使用します。