If it wasn’t for communicating with other scripts, I’d probably store all my variables as private.The issue with setting them as public variables is if I change their value later on in the code, it just doesn’t register. I have to change it to private then to public back again. It gets frustrating when I assume that I changed a variable’s value only to find out while debugging that I accidentally changed a public variable instead of setting it to private then public.
Not exactly sure what you’re talking about with changes not “registering”, but the more robust option in C# is properties. You can have fine grained control over the visibility of the getter and setter individually, and you can also provide custom implementations for getters and setters.
If you have a public variable that is of a type Unity can serialize, then you changing it in the script won’t change the value Unity has serialized on the game object in your scene.
If you want a public variable which Unity won’t serialize, then you can use the System.NonSerialed attribute or turn it into a property.
[System.NonSerialized]
public int MyInt;
private float myFloat;
public float MyFloat { get => myFloat; set => myFloat = value; }
This.
The reason why setting it private and back to public is working for OP, is because when it is set private Unity stops serializing it, it loses its serialized value, and then setting it public again it gets the latest ‘default value’.
Note that the default value:
public int myInt = 5; //5 being our default value
The default value is set when the object is constructed. But Unity comes along just immediately after constructing the object and goes through and sets all serialized values to what it has stored in the serialized representation for it. It can’t tell if the value it has in serialized form is the result of the previous default value you’ve changed, or the value you expect because you set it to that (otherwise why would it be serialized???). So it always favors the value that was serialized.
Also, if you want a private field that gets serialized… use the ‘SerializeField’ attribute:
[SerializeField]
private float myFloat;
Looks like I’ll be using the NonSerialized attribute, thanks. Are there any disadvantages to using nonserialized variables vs serialized ones?
They won’t show up in the Unity Editor inspector and they won’t be copied when using Instantiate.
It goes like this.
You have serialized/unserialized fields (fields are the name for class level variables).
Serialized fields show in the inspector and it allows you to modify their value in the editor. This way say you have a ‘Health’ script you can then attach it to various GameObjects in your scene and assign different levels of health to each object you attach it to. A rock gets 1000, a twig gets 1. You can then even create prefabs from these GameObjects and when you clone the prefab the values get duped with them.
If they’re not serialized, none of the above happen.
…
public/private (as well as protected/internal) have nothing to do with this. These are ‘access modifiers’ and pertain to the access level of the field by code outside the scope of the class. public members can be read/write, private can not. protected can be read/write by classes inheriting from that class, and internal can be accessed by anything in the same library/dll.
Where access modifiers intersect with serialization is that Unity treats all public fields as serialized fields, unless attributed with NonSerialized.
And it treats all private/protected/internal fields as non-serialized, unless attributed as SerializeField.