Reason(s) to [SerializeField] a private variable?

EDIT: Some good responses, thanks.

I was going through a script in the Standard Assets pack and came across variable creation like this

[SerializeField] private float m_MaxSpeed = 10f;

Is a reason to serialize a private variable to let it be changed in the inspector but not let it be accessed by other scripts? Looks that way; “If … you … want Unity to serialize one of your private fields you can add the SerializeField attribute to the field.” - Unity - Scripting API: SerializeField

Along that line of thought, is a reason we might not want that variable (and others in this script) to be accessible by other scripts is to “simplify” or minimize the number of variables pop up in the IDE “auto-finish” (Intellisense?) window? (I doubt this is it, though.) A similar reason? I’m trying to figure out why we wouldn’t just make the variable public.

1 Like

There are a lot of differing thoughts about accessibility, so there’s no one right answer to this. I personally always make fields private, and the reason doesn’t have to do so much with the inability of other scripts to access that value (you can still access it with reflection, the way Unity does when you “serialize” private fields), but more about the inability of the host class to detect when changes are made.

If a class has a field, chances are that it’s relying on the that field for some reason locally. You can’t possibly expect other classes to know the current state of that object, what operations it may be in the middle of, and how important the field maintaining its value is to what’s currently going on. To account for this, a good rule of thumb is to only expose properties and methods, not fields. By using a property, it becomes possible for the host class to respond to changes being made from external sources, validate changes, or block changes completely. That’s not to say that the class MUST do these things, but it makes it trivial to add validation at some point later, when it may be needed, without refactoring anything.

So yes, in my opinion it’s very important to get into the habit of making private fields, and serializing them with the attribute when you need to change their initial value in the inspector.

5 Likes

You are looking at it from the wrong angle. You should be looking for the reasons to make a variable public, not the other way around.

2 Likes

If you code for yourself only, it maybe isn’t important for you if variables are private or public, because you know why you need them anyway. But when you code for other developers (e.g. for asset store) or you work in collaboration with others, it’s important not to expose unnecessary things. So, why make something public and accessible to other classes if it’s only needed for the current class? But if you want it editable in inspector and still private, then you use [SerializeField].

3 Likes

Thanks folks. Good info here.

For custom editors the field needs to be serialized but autoproperties are not. This means sometimes you’ll have an interface variable with {get;set;} which you can’t find via a custom editor so you give it a private backing field and make it [SerializeField] then point the custom inspector code to that instead - thus satisfying the interface and the custom inspector.

1 Like

The first time you encounter a bug where you wrote a class never expecting a variable to be modified directly outside of the class, but you accidentally do so anyway, is where you will understand why to use “public” sparingly. But you may still want to customize via the inspector, so SerializeField is handy.

1 Like