When to use public or private variables for the inspector?

class MyClass1
private bool HelloInspector = false;

class MyClass2
   public bool HelloInspector = false;

I noticed that there are 2 ways of making variables show up in the inspector. You can either make it public (as in MyClass2) or make it private but insert ‘[SerializeField]’ before the variable (as in MyClass1). I just want to know if there is a key difference between the 2. Does anyone know that?

@lordCasper, actually there are 3, not just two ways. public, private and protected.

The key to this subject is part of the OOP paradigm called encapsulation. Entire books are published on the subject for various OO languages.

The issue of private or public (or protected) status is not really about the inspector. The serialization is a way to get the inspector to see values you declare private.

The concept behind objects (classes) is to create software components that fit together like parts in a machine. In older languages, like C, this wasn’t supported by the language. Everything was basically exposed publicly.

However, think about the alternator on an engine in a car. Inside modern alternators is a voltage regulator (that’s a separate part in older cars), a stator (the rotating stuff attaches to it, but the stator doesn’t move - it’s the ‘housing’), coils, magnets, etc. When they go bad, you replace the whole thing rather than take them apart to fix them. That’s an object.

The object, or class, has some kind of interface that faces the public. It may have dials, switches, etc. but it exposes only what the consumer of the class requires. Everything else that makes the object work is wrapped (encapsulated) inside, out of the view of the user. The interior components should probably not be messed with by users, as that may break the object.

When classes leave everything public, the public can do anything to them, including corrupt them. Certainly simple, naive classes have few such problems, but the more complex the class is, generally, the more likely the internals need to be well controlled.

Private functions are used for those which are not for the public’s use.

That public may be you if you’re the only consumer of the classes you create, but on more formal work that public may be members of a team, or it may be that you’ve written a library to be purchased or downloaded by a public of programmers.

Whatever the case, private members protect the internal workings of complex machines. The wrapper or outer case of the class is basically removed if there are no private members.

There are some, rare cases where everything in the class should be exposed, but these are usually collections of data in a structure which don’t need any protection.

Generally speaking, as you write, only those functions that users of the class should call are public. Anything you want protected from the public but should be accessible to classes derived from yours should probably be declared protected (half way between private and public). Everything else should be private until you find a really good reason to make them public.

You give the public the ability to read private values by providing public functions.

You can implement properties to control the i/o of values. This allows you to expose values as public for convenience, but maintain control of how they’re read and assigned when that is the primary purpose for protection. For example, if a class holds a float representing a radian, you want to enforce that the user can’t assign the radian a value out of range, so the ‘set’ portion of the property could enforce that upon assignment.

In the case of Unity’s magnitude, for example, in the various vector classes, the value is calculated from the basic data (x,y and or z) on demand using the ‘get’ portion of a property. However, magnitude (which is the length of the vector) is an expensive calculation requiring a square root, so unless code requests the magnitude it isn’t calculated at all. Further, as a property, if magnitude is requested, it isn’t a function so it isn’t calculated on every read - only the first time when it is unknown (or has been cleared by changing the basic data x, y or z). This means x, y or z must also be controlled, so that assigning any of them resets the status of a calculated property like magnitude.

Reading code like that of Vector3 can be informative on how these techniques are used in professional code.

It comes down to whether you want other scripts to “see” the field you create and personal style. If you only want to use the inspector to set an initial value, use private with SerializeField. If you need to refer to the field in another script, use public. Personally, I never make fields public. If I absolutely can’t get around access, I’ll make a public property that returns the private field. In more cases than not, I provide other scripts data with events and try not to make any data public.

I came from a Java background working with teams, encapsulation, specially Getters for private fields was a MUST for us working on individual modules, exposing what should or should not be to co-workers, they would come to us and ask if I can expose this field so they can do this or that, it was all features of encapsulations, but when I started a solo unity project, working with myself, there was no reason for all these, actually accessing fields directly without calling methods would give a micro-performance boost, using an accessor called internal instead of public also a consideration, it won’t serialize the field and prevent access from other assemblies outside of the game, I’m not informed about how cheat engine works when it access the Hex values and hacks your game data values, I don’t know if those private or public accessors can prevent that, would be glad to know that someday