シリアル化のルール
Conditions that determine whether fields in your scripts are serialized.
読み終わるまでの所要時間 11 分最終更新 1ヶ月前
Unity のシリアライザーは、特にランタイムで効率的に動作するように設計されています。そのため、Unity のシリアル化は、他のプログラミング環境のシリアル化とは異なる挙動をします。Unity のシリアライザーは、プロパティではなく C# クラスのフィールドで直接機能します。そのため、Unity は特定の条件を満たす場合にのみフィールドをシリアル化します。以下のセクションでは、Unity でフィールドのシリアル化を行う方法の概要を説明します。
フィールドシリアライゼーションを使用するには、フィールドが以下の状態であることを確認します。
-
または SerializeField 属性を持つこと。
public- ノート: 場合によっては、フィールドがシリアル化されます。詳しくはホットリロードを参照してください。
private
- ノート: 場合によっては、
-
でないこと。
static -
でないこと。
const -
でないこと。
readonly -
シリアラル化可能なフィールド型であること。
- プリミティブなデータ型 (int、float、double、bool、string など) であること。
- Enum 型 (32 バイト以下) であること。
- 固定サイズバッファであること。
- Unity の組み込み型 (例えば、Vector2、Vector3、Rect、Matrix4x4、Color、AnimationCurve) であること。
- Serializable 属性をもつカスタム構造体であること。
- UnityEngine.Object から派生したオブジェクトを参照すること。
- Serializable 属性を持つカスタムクラスであること。(カスタムクラスのシリアル化 を参照)。
- 上記のフィールド型の配列であること。
- 上記のフィールド型の であること。
List<T>
ノート: Unity は、マルチレベルの型 (多次元配列、ジャグ配列、辞書、ネストされたコンテナタイプ) のシリアル化をサポートしていません。これらをシリアル化するには 2 つのオプションがあります。
- ネストされた型をクラスまたは構造体でラップする。
- ISerializationCallbackReceiver を実装することにより、シリアル化コールバックを使用して、カスタムのシリアル化を実行する。
カスタムクラスのシリアル化
Unity がカスタムクラスをシリアライズするためには、クラスが以下の状態であることが必要です。
- Serializable 属性を持つこと。
- static でないこと。
UnityEngine.ObjectUnityEngine.Object[SerializeReference]- インラインでシリアル化:デフォルトでは、クラスを参照するフィールドに を指定しない場合、Unity はカスタムクラスを値によってインラインでシリアル化します。つまり、カスタムクラスのインスタンスへの参照を複数の異なるフィールドに保存する場合、それらはシリアル化されると別々のオブジェクトになります。フィールドをデシリアライズすると、それらは同一のデータを持つ異なる別個のオブジェクトを含みます。
[SerializeReference] - でシリアル化:
[SerializeReference]を指定する場合、Unity はオブジェクトをマネージ参照として確立します。ホストオブジェクトは、オブジェクトをそのシリアル化されたデータに直接保存しますが、専用のレジストリセクションに格納します。[SerializeReference]
[SerializeReference]- フィールドは null でも可。インラインのシリアル化では、null を表現できません。代わりに、null を未割り当てのフィールドを持つインラインオブジェクトに置き換えます。
- 同じオブジェクトへの複数の参照。を使用せずに、カスタムクラスのインスタンスへの参照を複数の異なるフィールドに格納する場合、それらはシリアル化すると別々のオブジェクトになります。
[SerializeReference] - グラフと循環データ (例えば、それ自体への参照を持つオブジェクト)。インラインクラスのシリアル化は、null や参照の共有をサポートしません。そのため、データの循環は、Inspector の動作の異常、コンソールエラー、無限ループなど、予期しない結果につながる可能性があります。
- ポリモーフィズム。親クラスから派生したクラスを作成し、親のクラスを型として使用するフィールドに割り当てる場合、なしに、Unity は親クラスに属するフィールドのみをシリアル化します。Unity はクラスインスタンスをデシリアライズするとき、派生クラスではなく、親クラスをインスタンス化します。
[SerializeReference] - データ構造体が、オブジェクトの配列位置をハードコードしたり配列全体を検索したりせずに、特定のオブジェクトを指し示す安定した識別子を必要とする場合。Serialization.ManagedReferenceUtility.SetManagedReferenceIdForObject を参照してください。
ノート: インラインのシリアル化はより効率的なので、 がサポートする機能の 1 つを特に必要としない限り、インラインのシリアル化を使用することをお勧めします。 の使用方法の詳細は、SerializeReference のドキュメントを参照してください。
[SerializeReference][SerializeReference]プロパティのシリアル化
Unity では、以下のような場合を除き、通常プロパティをシリアル化することはありません。
- プロパティが明示的なバッキングフィールドを持つ場合、Unity は通常のシリアル化ルールに従ってそれをシリアル化します。 例:
public int MyInt{get => m_backing;private set => m_backing = value;}[SerializeField] private int m_backing;
- Unity は、ホットリロード中にのみ、自動生成されたフィールドでプロパティをシリアル化します。
public int MyInt { get; set; }
自動生成されたフィールドを持つプロパティを Unity にシリアル化させたくない場合は、 属性を使用します。
[field: NonSerialized]