- Home /
Private Variables Serialised By Default
Hi all,
I think I need to submit this as a bug but I'm not entirely sure if this is not intended behaviour. I'm under the impression that private variables are not serialised by Unity unless you explicitly tell it to with [SerializeField]. But I was writing some editor scripts and discovered evidence to the contrary, code snippet below which shows this:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class NewBehaviourScript : MonoBehaviour
{
private bool abool;
private int anint;
private string astring;
public void Update()
{
Debug.Log( "Update" );
Debug.Log( this.abool );
Debug.Log( this.anint );
Debug.Log( this.astring );
this.abool = true;
this.anint = 423;
this.astring = "hello";
}
}
If you attach this class to a GameObject in a scene, you'll see in the console that "Update" is called, and all the values are at their defaults as they should be (false, 0, and blank). Then on the next call, they are true, 423, and "hello" as expected.
Now - clear your console, and then edit a script (like insert a space or something), save, and come back to unity and wait for it to compile. Once compilation has completed, it reloads the assemblies and Update is called again - but it keeps the values true, 423, and "hello". So clearly it is serialising these private variables, but why?
Just a stab, but try removing [ExecuteInEdit$$anonymous$$ode]... Also, put the code in Start() and not Update(). Update runs once a frame...
ExecuteInEdit$$anonymous$$ode is just there so that the Update function will run, this has happened in a project I'm working on where I'm setting data like this but via Editor scripts.
This still persists in 2016, caught me off guard. Honest to god I don't know if this is a bug or a feature, but when there isn't a word of this corner case in the docs, i'm gonna go with bug. Will report it tomorrow.
Answer by CHPedersen · Aug 15, 2013 at 05:20 PM
I think this is by design and probably caused by the ExecuteInEditMode tag. Read this blog entry about Unity serialization:
http://blogs.unity3d.com/2012/10/25/unity-serialization/
In short, I think it happens because ExecuteInEditMode is for Editor extension scripts, which may contain configuration information that has to survive assembly reloads. All the Mono assemblies (managed CLR assemblies) get reloaded every time you enter or exit Play mode. If values of variables set in Editor scripts did not survive this, it would reset all Editor script configurations every time you exited playmode. Imagine the repercussions of that: Suppose you have a GUI library like NGUI, EZGUI or iGUI which provides Editor classes. Variables which might store the position of windows or Style of buttons, all meticulously setup by the user, would get reset to their default on every run. It wouldn't be good. :)
That blog post specifically states that if you want any non public member variable serialised, it needs [SerializeField] on it.
Answer by drchilitopicoso · Dec 20, 2016 at 02:37 PM
[Update] I got a reply from a developer, things are indeed functioning as intended. They will update documentation to reinforce this. @CHPedersen is right. Taking a second look at the blog post he linked is mentioned that "Private fields are serialized under some circumstances (editor)" under the Some Serialization Rules part.
[OLD] I sent a report and it has been confirmed by QA that it is a bug, they will look at it. Until it's fixed, if your script has the [ExecuteInEditMode], you'll have to tag private variables with [NonSerialized] so they truly don't get serialized.
Will reply here again when it's fixed.