Unity がオブジェクトをシリアライズする前にコールバックを受信するためにこのメソッドを実装します。
コンストラクタを呼び出してしばしば自分でオブジェクトを作成しなければならない他の多くのプログラミング環境とは対照的に、
Unity は頻繁にオブジェクトを作成し、あらかじめ定めた値でエディターのフィールドを設定します。
オブジェクトのフィールドに設定するためのプロセスと、それらを取得することをそれぞれデシリアライズとシリアライズと呼びます。
Unity のシリアライザーは多くの種類のフィールドをシリアライズすることができますが、すべてをシリアライズできるわけではありません。シリアライズできない型の場合、特別な処理を行えるように Unity がフィールドを読み取る前か、書き込んだ後のコールバックを取得するといいかもしれません。このコールバックの典型的な使用例は、ユーザーはシリアライズ方法を知っていて、Unity にはシリアライズできないオブジェクトグラフがある場合などです。この場合、 ISerializationCallbackReceiver インターフェースを実装し、 Unity がフィールドを読み取る前に手動で Unity がシリアライズできる方法でオブジェクトグラフをフィールドへとシリアライズすることができます。逆のことを OnAfterDeserialize メソッドで実行できます。
インターフェースは例のような MonoBehaviour の上でを使用できますが、カスタムのクラスや構造体にも使用できます。
このインターフェースは非常に注意して使用する必要があります。Unity のシリアライザーは普段メインスレッド以外で実行されており、ほとんどの Unity API はメインスレッド上からの呼び出しにのみ対応しているからです。また、コードを Unity のシリアライズコードに挟まれて実行すると(コールバックは延期されません)、Unity が読み取りや書き込みをしているオブジェクトを修正することで、Unity のシリアライザーを酷く困惑させる可能性があります。このインターフェースは、上記のように Unity にはシリアライズできないものを自分自身で扱う場合にのみ使用することを強く推奨します。
もう1つの注意すべきことは、シリアライズは考えているよりも高頻度で起こることです。MonoBehaviour が実行時に Instantiate() で複製されたものを取得する場合、デシリアライズとシリアライズがなされます。オブジェクトが自身のゲームオブジェクトを参照するフィールドを持つとして、ゲームオブジェクトを複製した際にフィールドで古いオブジェクトではなく、新しいゲームオブジェクトを参照したい場合を考えます。これらの「内部参照」を更新するために Unity はシリアライゼーションシステムを使用します。Unity はすべてのフィールドを読み取り「複製されたもの」への参照を探し、新しい値をフィールドに書き込みます。Unity がシリアライズできないカスタムクラスでも内部参照の更新をできるようコールバックもまた更新時に実行されます。
現在、クラスだけがコールバックを受け取ります。構造体は受け取れません。
no example available in JavaScript
using UnityEngine; using System; using System.Collections.Generic;
public class SerializationCallbackScript : MonoBehaviour, ISerializationCallbackReceiver { public List<int> _keys = new List<int>(); public List<string> _values = new List<string>();
//Unity doesn't know how to serialize a Dictionary public Dictionary<int,string> _myDictionary = new Dictionary<int,string>() { {3, "I"}, {4, "Love"}, {5, "Unity"}, }; public void OnBeforeSerialize() { _keys.Clear(); _values.Clear();
foreach( var kvp in _myDictionary ) { _keys.Add( kvp.Key ); _values.Add( kvp.Value ); } }
public void OnAfterDeserialize() { _myDictionary = new Dictionary<int, string>();
for(var i = 0; i != Math.Min( _keys.Count, _values.Count ); i++ ) _myDictionary.Add( _keys[i], _values[i] ); }
void OnGUI() { foreach( var kvp in _myDictionary ) GUILayout.Label( "Key: " + kvp.Key + " value: " + kvp.Value ); } }
シリアライゼーションのコールバックを使用して Dictionary をシリアライズします。