• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by vexe · Sep 01, 2014 at 03:39 PM · serialization

OnBeforeSerialize is getting called rapidly?

Not sure if this is normal, but I noticed that OnBeforeSerialize is getting called very rapidly in-editor and at runtime - almost every frame.

 using UnityEngine;   
 
 public class Test : MonoBehaviour, ISerializationCallbackReceiver
 {
     public void OnBeforeSerialize()
     {
         Debug.Log("before");
     }
 
     public void OnAfterDeserialize()
     {
         Debug.Log("after");
     }
 }

I read in the docs that it's called before Unity 'reads' my objects' values - I don't think 'read' is quite a synonym to 'serialize' - they're using 'read'/'write' to 'serialization'/'deserialization' - not sure about that.

Is this how it's supposed to work? (called very rapidly) - if so, I think they should have named it something else cause 'OnBeforeSerialize' is miss-leading, unless I'm miss-understanding something here.

Cheers!


EDIT:

So I thought maybe cause I'm using some Unity API (Debug.Log) which the doc states that it wouldn't be preferred - but not the case, tried this:

 public int counter;

 public void OnBeforeSerialize()
 {
     counter++;
 }

And the value still changes very rapidly!

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TMPxyz · Nov 13, 2015 at 08:45 AM 0
Share

As it's marked as "By Design", It seems that's not going to change in near future, http://issuetracker.unity3d.com/issues/iserializationcallbackreceiver-dot-onbeforeserialize-is-called-every-oninspectorupdate

Is there some workaround for this problem?

I'm just facing the same problem when working with a tree data-structure. I have to say this behavior is quite... surprising.

3 Replies

· Add your reply
  • Sort: 
avatar image
4
Best Answer

Answer by Landern · Sep 04, 2014 at 07:10 PM

The documentation warns you that using this interface and the rapid calls right here:

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.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image vexe · Sep 05, 2014 at 05:31 AM 1
Share

@Landern Yes I read that of course. It mentions that it gets called many times in many situations. But it never mentions where it gets called 'rapidly' almost each frame when the object is just sitting there doing nothing (i.e. no cloning no etc) - Have you tried the example counter script above?

avatar image Landern · Sep 05, 2014 at 03:24 PM 1
Share

I would next read the blog post about the introduction to ISerializationCallbackReceiver, there are a LOT of gotcha's depending on how you construct objects, what they derive from and whether unity is going to just (de)serialize ad nauseam to ensure the internal stream has the newest information. If you go through the comments on the blog post they explain quite a bit, this includes sixtrillionbillion calls and why it may be happening.

avatar image vexe · Sep 05, 2014 at 05:53 PM 0
Share

Thanks will take a look

avatar image sarynth · Oct 04, 2020 at 05:09 PM 0
Share

I started to go to the blog post linked, but the next answer below this one answered the question in my case. When I have the Inspector focused on the Scriptable Object asset, it's serializing the value every frame to display in the inspector. When I clicked to inspect something else, it stopped being called. Very cool

avatar image
8

Answer by Tryz · Sep 24, 2014 at 12:40 PM

I would agree that "happens more often than you might think" doesn't really equate to "every frame".

Here's what I found for OnBeforeSerialize:

  1. Called once before a recompile is handled by the Unity Editor

  2. Called multiple times when the scene is saved (ie two or three times)

  3. Called every frame if the inspector for the object is open in the editor

  4. Not called in an actual build (in my simple test)

Here's what I found for OnAfterDeserialize:

  1. Called once after a recompile

  2. Called once after the scene is loaded

  3. Called once in an actual build (in my simple test)

So, if you have the editor open and an inspector open. OnBeforeSerialize is called every frame by the OnInspectorUpdate function. So far, there doesn't seem to be a way for me to stop or interrupt this.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Deni35 · Nov 27, 2016 at 05:20 PM 0
Share

What is the point to call OnBeforeSerialize every frame if inspector is opened?

avatar image Bunny83 Deni35 · Nov 27, 2016 at 05:50 PM 0
Share

The inspector works soley on the serialized data of the objects. It uses the SerializedObject and it's SerializedProperty objects. Each time those are "read" (whenever the inspector redraws) the serialized data need to be updated.

avatar image Sanctus2099 Bunny83 · Aug 31, 2017 at 11:53 AM 0
Share

That's the key there "whenever the inspector redraws". I did however add a log in the OnInspectorGUI method and one on OnBeforeSerialize. The first one is logged once or so and the other one is constantly called.

avatar image
2

Answer by DaCookie · Jun 15, 2020 at 02:02 PM

This is an old thread, but here's a workaround.

I have a ScriptableObject that have some properties exposed in the inspector, but I use the serialization callbacks to serialize a non-serializable data (as an example, I'm serializing a dictionary).

In order to avoid serialization if it's not needed, I use the Unity's dirty flag. This flag is enabled when an exposed property is changed in the inspector. So if this flag is set to true (and so a property has been modified), I let the serialization happen, then I remove the dirty flag.

 public void OnBeforeSerialize()
 {
     #if UNITY_EDITOR
     if(UnityEditor.EditorUtility.IsDirty(this);
     {
         SerializeDictionary();
         UnityEditor.EditorUtility.ClearDirty(this);
     }
     #else
     SerializeDictionary();
 }
 
 private void SerializeDictionary() { /* ... */ }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image iliaJelly · Apr 13, 2021 at 06:34 AM 0
Share

You are onto something,

avatar image iliaJelly · Apr 13, 2021 at 08:38 AM 0
Share

However, according to my findings, If you do .ClearDirty() than you will prevent the Asset from being saved to Disk.

Assets are saved to disk whenever AssetDatabase.SaveAssets() is called, Or the Save Project from menu is pressed.

the IsDirty flag gets cleared by itself when asset is saved to Disk. So I would not do .ClearDirty(), this still means that it would run every frame after it was changed, and before SaveAssets() is called. But thats better than nothing

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

31 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

In this case the lists do not serialize. Why? 2 Answers

Client sends bytes when another player moves 0 Answers

Change values of variables in System.Serializable 1 Answer

How to re-serialize assets so they are stored as text? 1 Answer

Multiplayer data exchange 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges