Unity はシリアル化を使って シーン、アセット、アセットバンドル をデバイスのメモリに (または、メモリから) ロードして保存します。これには、独自のスクリプティング API オブジェクトに格納される MonoBehaviour コンポーネントや ScriptableObject などのデータも含まれます。
Unity エディターの機能の多くは、基軸となるシリアル化システム上に構築されています。シリアル化で特に気を付けるべき 2 つの点は Inspector ウィンドウ とホットリロードです。
Inspector ウィンドウには、表示中のオブジェクトのシリアル化されたフィールド値が表示されます。Inspector 内で値を変更すると、Inspector はシリアル化されたデータを更新し、デシリアライゼーションをトリガーして表示中のオブジェクトを更新します。
Unity のビルトインオブジェクトも、MonoBehaviour から派生したクラスなどのスクリプトオブジェクトも同様です。
Unity は、Inspector ウィンドウで値を表示したり変更したりする際に、C# のプロパティゲッターやセッターを一切呼び出しません。代わりに、Unity はシリアル化されたバッキングフィールドに直接アクセスします。
スクリプトコードのホットリロードは、アセットデータベースの更新の一環として実行されます。ホットリロードとは、エディターの実行中に、再起動せずにコード変更を直接リロードして適用する処理を指します。詳細は、アセットデータベースの更新 と ホットリロード を参照してください。
ノート: ホットリロードはシリアル化の特殊なケースです。他のケースのシリアル化とは異なり、private フィールドは、 SerializeField 属性を持たなくても、リロード時にデフォルトでシリアル化されます。
Unity は以下のようにスクリプトを再ロードします。
[SerializeField] 属性がなくても、シリアル化の要件を満たすすべての変数 (プライベート変数を含む) を復元します。例えば、スクリプトからリロードした後に参照を NULL にしたい場合など、private 変数を復元しないようにする必要がある場合があります。この場合は、[field: NonSerialized] 属性を使用します。プレハブ は 1 つまたは複数の ゲームオブジェクト または コンポーネント のシリアル化されたデータです。プレハブインスタンスには、プレハブソースとその変更リストの両方への参照が含まれています。変更は、その特定のプレハブインスタンスを作成するために、プレハブソースに行う必要があります。
プレハブインスタンスは、Unity エディターでプロジェクトを編集している間だけ存在します。Unity エディターは、プレハブソースとプレハブインスタンスの変更の 2 つのシリアル化データからゲームオブジェクトをインスタンス化します。
シーンに存在するすべてのもの (プレハブやゲームオブジェクトなど) で Instantiate を呼び出すと、以下が行われます。
UnityEngine.Object から派生するものすべてをシリアル化することができます。UnityEngine.Objects が参照されているかをレポートします。すべての参照された UnityEngine.Objects を確認し、それらが Unity がインスタンス化したデータの一部であるかどうかを確認します。参照がテクスチャのような外部の何かを指している場合は、その参照をそのまま保持します。参照が子ゲームオブジェクトのような内部の何かを指している場合は、対応するコピーの参照を適用します。
EditorUtility.UnloadUnusedAssetsImmediate は Unity ネイティブのガベージコレクターであり、標準の C# ガベージ コレクターとは異なる目的を持ちます。シーンをロードした後に実行され、参照されなくなったオブジェクト (テクスチャなど) を確認して安全にアンロードします。Unity ネイティブのガベージコレクターは、オブジェクトが外部の UnityEngine.Objects へのすべての参照をレポートするバリエーションでシリアライザーを実行します。これは、あるシーンで使用されたテクスチャを、ガベージコレクターが次のシーンでアンロードする方法です。
シリアル化のほとんどはエディターで行われ、デシリアライズはランタイムに集中して行われます。Unity は一部の機能をエディターでのみシリアル化しますが、他の機能はエディターとランタイムの両方でシリアル化できます。
| 機能 | Editor | ランタイム |
|---|---|---|
| バイナリ形式のアセット | 読み込み/書き込み対応 | 読み込み対応 |
| YAML 形式のアセット | 読み込み/書き込み対応 | サポートなし |
| シーン、プレハブ、その他のアセットの保存 | 再生モード以外でサポート | サポートなし |
| JsonUtility による個々のオブジェクトのシリアル化 | JsonUtility による読み込み/書き込みのサポート EditorJsonUtility による追加のオブジェクトタイプのサポート |
JsonUtility による読み込み/書き込み対応 |
| SerializeReference | サポートあり | サポートあり |
| ISerializationCallbackReceiver | サポートあり | サポートあり |
| FormerlySerializedAs | サポートあり | サポートなし |
オブジェクトは、UNITY_EDITOR スクリプトシンボル 内でフィールドを宣言するときのように、エディターだけがシリアル化する追加フィールドを持つことができます。
public class SerializeRules : MonoBehaviour
{
#if UNITY_EDITOR
public int m_intEditorOnly;
#endif
}
この例では、m_intEditorOnly フィールドはエディターでのみシリアル化され、ビルドには含まれません。これにより、エディターでのみ必要なデータをビルドから省いてメモリを節約できます。そのフィールドを使用するコードも、例えば #if UNITY_EDITOR ブロックで条件付きコンパイルし、ビルド時にクラスがコンパイルできるようにする必要があります。
エディターは、Unity がランタイムにのみシリアライズするフィールドを持つオブジェクトをサポートしていません (例えば、UNITY_STANDALONE ディレクティブ内でフィールドを宣言する場合など)。