Version: 5.3 (switch to 5.4b)
ЯзыкEnglish
  • C#
  • JS

Язык программирования

Выберите подходящий для вас язык программирования. Все примеры кода будут представлены на выбранном языке.

ISerializationCallbackReceiver.OnBeforeSerialize

Предложить изменения

Успех!

Благодарим вас за то, что вы помогаете нам улучшить качество документации по Unity. Однако, мы не можем принять любой перевод. Мы проверяем каждый предложенный вами вариант перевода и принимаем его только если он соответствует оригиналу.

Закрыть

Ошибка внесения изменений

По определённым причинам предложенный вами перевод не может быть принят. Пожалуйста <a>попробуйте снова</a> через пару минут. И выражаем вам свою благодарность за то, что вы уделяете время, чтобы улучшить документацию по Unity.

Закрыть

Отменить

Руководство
public function OnBeforeSerialize(): void;
public void OnBeforeSerialize();

Описание

Implement this method to receive a callback before Unity serializes your object.

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.

The interface can be used on MonoBehaviours like in the example, but it can also be used on custom classes and structs.

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.

Currently only classes will receive the callbacks. Structs will not.

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 ); } }

Using serialization callbacks to serialize a Dictionary.