public void OnBeforeSerialize ();

説明

Unity がオブジェクトをシリアライズする前にコールバックを受信するためにこのメソッドを実装します。

In contrast to many other programming environments where you often creates objects yourself by invoking constructors, Unity will often create objects for you, and set its fields with the values that you set for them in the Editor.

The process of setting the fields of your objects, and getting them, is called deserialization and serialization respectively. Unity's serializer is able to serialize many different kinds of fields, but not all of them. In those cases it can be convenient to get a callback before Unity will read from your fields, or after it has written to them, to allow you to do some custom steps. A typical use case for this would be if you have an object graph that you know how to serialize, but Unity does not. In that case, you can implement ISerializationCallbackReceiver interface, and before Unity will read your fields, you manually serialize your object graph into your fields in a way that Unity can serialize. You can do the reverse in the OnAfterDeserialize method.

インターフェースは例のような MonoBehaviour の上でを使用できますが、カスタムのクラスや構造体にも使用できます。

This interface should be used very carefully. Unity's serializer usually runs on the non main thread, while most of the Unity API can only be called from the main thread. Your code is also running interleaved with Unity's serializing code, (the callbacks are not deferred), so you could seriously confuse Unity's serializer by modifying the very objects Unity is reading from and writing to. You're strongly recommended to only use this interface for the example use case mentioned above: serializing something yourself that Unity doesn't know how to.

Another caveat is that serialization happens more often than you might think. When a MonoBehaviour gets cloned through Instantiate() at runtime, it gets deserialized and serialized. If the object had a field that pointed to its own gameObject, when that gameObject gets cloned, you'd want the field to point to the new gameObject, not the old one. In order to update these "internal references", Unity uses the serialization system. Unity reads all your fields, finds references to "things that were cloned", and then writes the new values in your fields. The callbacks will also be invoked for this updating phase, allowing you to make the updating of internal references to also work in your custom classes that Unity cannot serialize.

現在、クラスだけがコールバックを受け取ります。構造体は受け取れません。

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 をシリアライズします。