Lets say you have a variable in a class. You want functions in the class to be able to alter that variable, and you want outside classes to be able to read that variable, but you don’t want outside classes to be able to modify it. You can use a property to expose only the read functionality, you can also set the access modifier of the get & set functionality differently.
It also lets you execute code as a part of the act of reading/writing to the property. Why you would want to do this depends on your use case, but a very simple example would be that you could have an integer, and every time you read from this integer it gets incremented by 1 so every ready gets a new number. Or a setter that takes a string could parse it and do things like fix the capitalisation before putting it into the variable.
Or perhaps there’s something that needs to happen whenever a variable is changed. If i have a wall defined by its start and end position, then whenever those are changed i want the wall to update itself so that it fits along the new positions. I could have the setters for StartPosition and EndPosition automatically call the UpdateWall function whenever the start/end positions are moved. Or maybe i have a script that highlights the object it’s attached to. When the user sets the ‘highlighted’ property to true the setter changes the variable then executes the code to actually highlight the object.
You could also have no variable behind it at all. Another very simple example. You have a wall that is defined by its start and end positions. You could have a property called ‘Length’ that has no setter and the getter returns vector3.Distance(Start,End).
It’s also just convention and good practice not to expose things more than they need to be exposed. Properties give you much more control over the way things are exposed.
The first sample uses properties to handle the outside access to your internal member, where the second example just exposes a public member that references the internal member.
Main difference is that a property allows way more control over what happens to the value of the internal member.
For example, with a property you can restrict access to an internal member to only read access by omitting the setter:
private string name;
// read only property
public string Name
{
get { return name; }
}
Or you can make sure the value set is allowed:
private string name;
public string Name
{
get { return name; }
set
{
if(value.ToUpper() == "VALID" )
{
name = value;
}
}
}
// here the internal member will not be updated;
Name = "invalid";
// here it will
Name = "valid";
In general it is a best practice to never expose fields to external code as they are considered implementation details. So in general as a rule of thumb, for all classes outside of monobehaviours use properties over fields where possible.
For Monobehaviours it’s a bit more difficult thanks to Unity itself (damn you devs/tutors!!) as they tend to use public fields in tutorials but private fields with the [SerializeField] attribute in sample projects. Personally I prefer the latter, though if implemented correctly public fields tend to not be a big problem. Reason for public fields is that they are serializable (hence the need for the attribute on private fields).