Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • 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 Tarlius · Oct 08, 2013 at 07:38 AM · c#serializationeditorwindow

Inconsistancies between EditorWindow and MonoBehaviour Serialization

Its my understanding that that all scripts are supposed to get serialized and rebuilt upon entering and exiting play mode, and that only public fields and [Serializable] fields are included in the serialization. However, this doesn't seem to be the case for editor scripts...

Private and unspecified (protected?) bool appear to be getting serialized since their values don't get reset whereas the [System.NonSerialized] value does...

I always thought [System.Serializable] just flagged the class as something that can be considered for serialization, not something where every field should be serialized, and experience with working with Unity serialization in MonoBehaviour supports this (I've also included a script that shows it)...

Is my understanding of what [System.Serializable] does flawed? Or is this just a bug?

Googling didn't come up with anything particularly concrete, only that "if you want it serialized, use System.Serializable".

I also noticed that the OnDisable/OnEnable rotation only happens when entering play mode and recompiling, and not when exiting...

Anyway- The code:

 using UnityEngine;
 using UnityEditor;

 public class EditorSerializationTest : EditorWindow {
     [MenuItem("Tarlius/Open Serialization Window Test")]
     static void EditorSerializationWindowTest() {
         EditorWindow.GetWindow<EditorSerializationTest>();
     }

     [SerializeField] DataHolder dataHolder = null;

     void OnEnable() {
         if(dataHolder == null) dataHolder = new DataHolder();
         dataHolder.OnEnable(); 
     }
     void OnDisable() { dataHolder.OnDisable(); }
     void OnGUI() { dataHolder.OnGUI(); }
 }

 [System.Serializable]
 public class DataHolder {
     bool defaultBool = false;
     public bool publicBool = false;
     [System.NonSerialized] bool nonSerializedBool = false;
     [SerializeField] bool serializedBool = false;

     public void OnGUI() {
         if(GUILayout.Button("Set True" )) Set(true );
         if(GUILayout.Button("Set False")) Set(false);
         if(GUILayout.Button("Status"))    LogButton();
     }

     public void OnEnable()  { Log("Enable:");  }
     public void OnDisable() { Log("Disable:"); }
     public void LogButton() { Log("Button:");  }

     public void Set(bool value) {
         defaultBool = value;
         publicBool = value;
         nonSerializedBool = value;
         serializedBool = value;
     }

     void Log(string context) {
         Debug.Log(context);
         Debug.Log("default" + defaultBool.ToString());
         Debug.Log("public" + publicBool.ToString());
         Debug.Log("nonSerialize" + nonSerializedBool.ToString());
         Debug.Log("serialized" + serializedBool.ToString());
     }
 }

Use the menu item to open the window, press the button to set all the fields to true, then enter play mode. Trues go in, all but the NonSerialize gets trues back. And for those interested, here is a MonoBehaviour that shows the inconsistency. Make a gameObject in edit-mode, use the menu to set all to true, and then enter play mode. In OnEnable only the public and SerializeField come back true (which is what I expect).

 using UnityEditor;
 using UnityEngine;

 public class SceneSerializationTest : MonoBehaviour {
     [MenuItem("Tarlius/Set SceneTest True")]
     static void SetupSceneTest() {
         SceneSerializationTest sf = GameObject.FindObjectOfType(typeof(SceneSerializationTest)) as SceneSerializationTest;
         sf.dataHolder.Set(true);
     }

     [SerializeField] DataHolder dataHolder = null;

     void OnEnable() {
         if(dataHolder == null) dataHolder = new DataHolder();
         dataHolder.OnEnable(); 
     }
     void OnDisable() { dataHolder.OnDisable(); }
     void OnGUI() { dataHolder.OnGUI(); }
 }
Comment
Add comment
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

2 Replies

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

Answer by numberkruncher · Oct 08, 2013 at 10:16 AM

Private fields are serialized under some circumstances (editor).

http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-Megapost

You shouldn't need to add System.Serializable to your MonoBehaviour, ScriptableObject or EditorWindow classes since these are serialized anyway, though you do need this attribute for custom data classes.

Comment
Add comment · 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
-1

Answer by Jamora · Oct 08, 2013 at 08:16 AM

I have the same understanding of [System.Serializable]: it only flags the class as something that can be considered for serialization. In Unity, by default, all public primitive types are serialized, and other Unity types (the list is here).

Unity says it does not serialize private fields, yet your test shows otherwise. This is because your DataHolder class is NOT a Unity class; it extends from System.Object, thus none of the Unity rules apply on it. And apparently, the .NET framework will serialize all primitives, private or not. Interestingly enough, when I tried to test this by making DataHolder a ScriptableObject, my Unity crashes.

Unity does not serialize when switching state from play to editor mode. That could cause potentially harmful side-effects because of the changed state during gameplay. There are ways around this, but you'll need a custom serializer (the asset store has a few) or you could make your own that saves data as assets to disk and then reloads them.

Also the default access modifier (unspecified) is private.

Comment
Add comment · Show 5 · 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 numberkruncher · Oct 08, 2013 at 08:29 AM 0
Share

For EditorWindow's the rule is slightly different. Private fields are serializable by default and must be disabled using the NonSerialized attribute.

Note for UnityScript users, the default access modifier if unspecified is public.

avatar image Tarlius · Oct 08, 2013 at 08:43 AM 0
Share

Unity says it does not serialize private fields, yet your test shows otherwise. This is because your DataHolder class is NOT a Unity class; it extends from System.Object, thus none of the Unity rules apply on it.

At first I had an "ah-huh" moment, but then I realised that cannot be true. Note that I am using the same class (ie: the one inheriting from System.Object) across both the tests and getting different results. Perhaps the editor uses a different serialization that is more true to the .NET implementation or something? I was not aware of .NET enforcing serialization on private stuff too (I've only ever used Unity's implementation).

Unity does not serialize when switching state from play to editor mode. That could cause potentially harmful side-effects because of the changed state during gameplay.

It does, however do the OnDisable/OnEnable loop (if [ExecuteInEdit$$anonymous$$ode] is used), and deserializing (to restore the state of the object stored in the scene before play). And thank god it does! $$anonymous$$y problem is that I'm relying on the data getting reset in an editor script, and it isn't! I can easily work around the problem, but I'm trying to work out why it isn't behaving as expected. I don't want to submit a bug report if its expected and I've missed something trivial though!

Also the default access modifier (unspecified) is private.

Of course it is. You can't access stuff in base classes from child classes without explicitly making it protected. What was I thinking? ><

avatar image Tarlius · Oct 08, 2013 at 08:50 AM 0
Share

For EditorWindow's the rule is slightly different. Private fields are serializable by default and must be disabled using the NonSerialized attribute.

Got a source for this? That was kinda the conclusion I came to, but I want to see it in docs or hear some reasoning before I stop seeing it as a bug. Its probably worth noting that if [System.Serializable] isn't used nothing gets serialized though.

avatar image numberkruncher · Oct 08, 2013 at 08:57 AM 0
Share

Private fields are serialized under some circumstances (editor).

http://forum.unity3d.com/threads/155352-Serialization-Best-Practices-$$anonymous$$egapost

You shouldn't need to add System.Serializable to your $$anonymous$$onoBehaviour, ScriptableObject or EditorWindow classes since these are serialized anyway, though you do need this attribute for custom data classes.

avatar image Tarlius · Oct 08, 2013 at 09:43 AM 0
Share

Don't get the "why" but thats pretty official. I was hoping for something more... "Satisfying". If you want to put that in an answer I'll accept it. I've read that passage before in a blog post I think but didn't notice/remember that caveat. Nice catch!

Either way, I guess its not a bug...

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.

Follow this Question

Answers Answers and Comments

17 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

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

SerializedProperty and PropertyField NullReference 1 Answer

Custom Editor window loses values on play. 1 Answer

EditorWindow member serialization in OnDisable 2 Answers


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