- Home /
Private vs NonSerialized
At the top of one of the tutorial Unity scripts there is a big long list of "@System.NonSerialized" variables. I understand this is so they don't show up in the inspector, but for variables that I'm 99% sure I'll only be using within this script itself would it be better to go through and make them all private vars? It'll make my script shorter, neater and would be faster to add new variables. But would there be any performance difference?
Performance wise I don't know(I think it will only work in the editor so when you build your game you should have no worries about less performance). But using NonSerialized is handy if you do not want a variable to show up in the inspector, but still want to access a variable using getComponent from other script and such.
I'm pretty sure most of these are not necessary to be public. But I can't figure out why the Unity developer would've used NonSerialized ins$$anonymous$$d of private… I thought private variables were better performance/memory-wise but it's highly likely I'm wrong.
Can't say for sure, but I am more of a system.NonSerialized-man. I like to nonSerialize them more than I like to make them private, mostly its just preference I guess.
Answer by Owen-Reynolds · Feb 03, 2012 at 04:31 PM
A real use for private: Suppose orcScript has a hitPoint var. When the orc gets hit, the sword script does orcThatGotHit.hitPoints-=damage;
and checks for death.
Now you add pits and explosions that also hurt orcs -- they also subtract from HP and check for death. Then you add a bloodSpray -- you add blood code (maybe just a function call) to swords, pits and explosions. After a while, you realize that for the "sword of wounding" DoT effect, programmers are just subtracting from hitPoints, and not checking for death or adding blood. There's way too much code to copy around.
So, you create a function in orcScript something like getHit(damage, location, damageType)
. It changes HP, checks for death, makes the blood, does the lifeBar... . You tell everyone to run just orcThatgotHit.getHit(5,hit.point,"fire");
instead of the old changing HP, death check ... .
But, some of the old code still just changes HP, and sometimes you forget and just change HP when you write new stuff (hitPoints is right there in the pop-up.) So, you go to orcScript and make hitPoints be private. Now all the old code in other scripts that used HP directly shows up as easy to find and fix errors, and you can never change HP directly again -- won't even see it in the Inspector. If you bring a new guy in, to write fireBomb code, they will automatically use getHit to do orc damage, without you even needing to explain it to them.
For a NonSerializeable example, suppose someone in game can change clothes. You want to personally save that using C#'s built-in file-writing abilities. You can auto-save the names of the clothes, the sizes ... but C# doesn't know how to automatically save a Unity texture.
So, you save the texture name, "softwool". On a Continue, you read the name and load Unity's softWool texture from the Resources folder. To tell C# not to try saving the Texture when you use the SaveToFile command -- it doesn't need to and it can't -- you mark it as NonSerializable.
Thanks for the detailed explanation, Owen. I'm still new at this but between yours and Bunny's answers it's helping me better understand the purposes of different variables. Although unfortunately I still can't figure out the proper etiquette of declaring member variables at the top of a script. (Note: I'm coding in Unity's javascript). I've read tutorials that say to use a public variable when you want it in the inspector and a private when you want it hidden, yet the bundled Unity scripts use the NonSerialized method for hiding. Just trying to figure out the best practices for writing bog-standard member variables. I guess I'll figure it out as I learn more.
A nonSerialized variable isn't written to disk when you quit, so it saves space (and makes it start up faster, not having to read it.) But, there are so many ways to improve programs. They worry about everything, but it isn't really worth you worrying about something that small.
A private variable isn't written to disk upon quitting either.
So it seems it's down to personal preference then. I'll go with private variables ins$$anonymous$$d of NonSerialized — It's less code.
The best thing is to always use public, at first. For testing, seeing it change in the Inspector is great. I often convert my real private vars temporarily into public, just so I can do this.
If you just want it Inspector hidden, use HideInInspector. The real reason for private is, eventually you will have scripts talking to each other, using each other's variables. Private
means you want other scripts to not even see it in the dropdown (and an error if you type it in it anyway.)
Answer by Bunny83 · Feb 03, 2012 at 03:31 PM
Ok, you have to distinguish the actual usage of these things. That a variable is not shown in the inspector is just a side effect:
- access modifier like
public, private, protected, internal
are used to seperate your variables / classes / methods from those you want to be accessible from outside and those you use inside a class. This is part of the encapsulation. A class is written for a specific task. It provides variables / properties / methods which can be used by the user of the class. Class internal stuff should be protected from outside manipulations. - NonSerialized is an attribute of a field which tells the system that uses this class, when ever this class is serialized (stored somewhere else) to not include this field. e.g. In Unity an object placed in a scene gets saved / stored in the scene file when the scene is saved. Serialized members are stored in the scene, nonserialized are not.
- HideInInspector is also an attribute which tells the Unity inspector, beside it's normal behaviour, to not show this field in the inspector. Usually all public members are serialized as long it has a type which can be serialized. private variables are usually not serialized by Unity.
- SerializeField is another attribute which tells the Unity serializer to serialize this field, even when it's private.
All those things have a different purpose / intention. Generally there's no performnce difference between public and private. The fact whether it's serialized or not is a different story. You have to think about for what you need a specific variable / method and choose the desired access-type (public / private / protected). Beside the access you have to think about if you want it's value to be serialized (stored) or not. And finally if it should be visible in the inspector ot not.
One thing ahead: If you want a private variable to show up in the inspector, you haven't understand a single word of this post ;)
I believe I'm following you (although still trying to grasp the whole classes concept) but to me it appears logical to define all your member variables as public or private depending on whether you need them to show in the inspector, with the exception of relatively fringe cases. $$anonymous$$g., Where you need public access without it showing in the inspector then use NonSerialized. Why would the developer have used NonSerialized member variables when nearly all of them are only used internally? Why not set them as private? — This is mainly what I don't understand.
Okay, I think I'm following this and still want to make a private variable public. I'll give you the scenario and you let me know if I'm crazy.
I'm making a tool to be sold on the asset store, which will have a set of variables that all need to be accessed via the inspector in the editor. However, I don't want the users accessing them accidentally (or on purpose for that matter!) from another script.
In this, admittedly rare, case... should I use a private variable with [SerializeField] to expose it in the inspector?
Your answer
Follow this Question
Related Questions
public private and static variables in js 1 Answer
RTS Style Selection system (How to control one unit and not the others) 2 Answers
How faster is private variables over public variables? 1 Answer
Private Serialized vs Public, The Actual Effect on a Game 1 Answer
Can you make a variable modifiable ONLY by the Inspector? 2 Answers