シリアル化 (シリアライゼーション) は、データ構造やゲームオブジェクトの状態を Unity が保存して後で再構築できる形式に変換する自動処理です。
Unity プロジェクトのデータを整理する方法は、Unity がそのデータをシリアライズする方法に影響し、プロジェクトのパフォーマンスに重大なインパクトを与える可能性があります。ここでは、Unity のシリアル化のための概要と、プロジェクトの最適化方法について説明します。
このセクションでは、以下のトピックについて説明します。
Unity のシリアライザーは、特にランタイムに効率的に動作するように設計されています。このため、Unity でのシリアル化は他のプログラミング環境でのシリアル化とは挙動が異なります。Unity のシリアライザーは、C# のクラスのプロパティではなく、フィールド に直接作用します。そのため、フィールドがシリアル化されるために準拠しなければならない規則があります。次のセクションでは、Unity でフィールドシリアライゼーションを使用するための概要を説明します。
フィールドシリアライゼーションを使用するには、フィールドが以下の状態であることを確認します。
List<T> であること。ノート: Unity は多階層型 (多次元配列、ジャグ配列、辞書、ネストしたコンテナ型) のシリアライゼーションをサポートしていません。これらをシリアライズする場合、2 つのオプションがあります。
Unity がカスタムクラスをシリアライズするためには、クラスが以下の状態であることが必要です。
UnityEngine.Object から派生したクラスのインスタンスをフィールドに割り当てそのフィールドを保存する場合、Unity はフィールドをシリアライズしてそのインスタンスへの参照にします。Unity はそのインスタンス自体を個々にシリアライズします。そのため、インスタンスに複数のフィールドが割り当てられても重複しません。しかし、UnityEngine.Object から派生しないカスタムクラスの場合、Unity はインスタンスの状態を、それらを参照する MonoBehaviour や ScriptableObject のシリアル化されたデータに直接加えます。inline と SerializeReference の 2 つの方法があります。
SerializeReference を指定しない場合、Unity はカスタムクラスを値によってインラインでシリアライズします。つまり、カスタムクラスのインスタンスへの参照を複数の異なるフィールドに保存する場合、これらはシリアライズされると別々のオブジェクトになります。それらはシリアライズされると別々のオブジェクトになります。そして、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 のシリアライザーがサポートしないもの (例えば、C# の Dictionary) をシリアル化したい場合があるかもしれません。最良の方法は、ISerializationCallbackReceiver インターフェースをクラスで実装することです。これにより、シリアライゼーションとデシリアライゼーション中の重要なポイントで呼び出されるコールバックを実装することができます。
OnBeforeSerialize() コールバックを呼び出します。このコールバックの内部で、データを Unity が理解できるものに変換することができます。例えば、C# の Dictionary をシリアライズする場合、データを Dictionary からキーの配列と値の配列にコピーします。OnBeforeSerialize() コールバックが完了した後、Unity は配列をシリアライズします。OnAfterDeserialize() コールバックを呼び出します。このコールバックの内部で、データをメモリのオブジェクトに都合の良い形に変換して戻すことができます。例えば、キーと値の配列を使用して、C# Dictionary を再入力します。Unity はシリアル化を使って シーン、アセット、アセットバンドル をデバイスのメモリに (または、メモリから) ロードして保存します。これには、独自のスクリプティング API オブジェクトに格納される MonoBehaviour コンポーネントや ScriptableObject などのデータも含まれます。
Unity エディターの機能の多くは、基軸となるシリアル化システム上に構築されています。シリアル化で特に気を付けるべき 2 つの点は