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?
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 ;)
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.