Making Variables Visible in the Inspector
In my previous article I looked at how we can apply information hiding to our scripts to potentially reduce the amount of code we need to rewrite when we make changes, and to help minimise bugs. One problem that you might have noticed when reading this post is that by making our variables private, we lose access to a big feature of Unity, accessing values in the inspector.
Having access to values in the inspector is beneficial as it allows us to easily modify properties of our game objects such as changing the speed in which a character can run, or how high they can jump. We are even able to do this whilst the game is running. On top of that we can drag game objects and components into inspector fields to give us easy access to other objects we want to communicate with.
There are a lot of great benefits to using the inspector that we wouldn’t want to lose out on. Luckily, we don’t have to, all we must do is make use of an attribute called SerializeField. We simply place the attribute above the code we want to serialise and boom we have our private variable available in the inspector.
[SerializeField]
private float _maxHealth = 100;
Serialisation
Serialisation is the process of saving the state of an object so that we can make use of it in some way later. A serialised object can be saved in many different locations like in memory, to a file stored on your hard disk, or a database stored on a remote server. The state of our object is simply the data we have in our variables. So, if we had a script called Player we might serialise the state of the player such as their health, the weapons they were carrying, what level they are, the amount of experience they currently have and so forth. We could save this data to the hard drive when the player exits the game, and have it load back up when they load the game back up again.
Serialisation in Unity
Unity uses serialisation throughout its engine for prefabs, saving scenes, and lots of other things including what we are concerned with in this article, the inspector. If you want to read more about how Unity uses serialisation then I will leave a link to the Unity blog post at the bottom of this article.
When viewing data in the inspector the Unity engine doesn’t interact with the C# script but instead requires that the script be serialised and made viewable in the inspector by reading serialised version of the script. Unity has a lot of rules and requirements about which data gets serialized, for instance you cannot serialise dictionaries, and as we already know Unity doesn’t serialize variables marked as private.
However, as we have seen, when we want to follow certain coding best practices such as information hiding, we want to make our variables private whenever it makes sense to do so. The developers behind the Unity engine obviously undersatnd that we may want to have variables both private and available in the inspector so accommodate for this with the attribute SerializeField.
C# Attributes
Attributes are a feature of the C# language that essentially allow us to tag parts of our code such as methods, functions, structs, and fields (our scripts variables) and have these tags provide additional information about them.
An attribute is just a class like anything else we write in C#, including the fact that they contain methods, and store data. The main differences are that they inherit from System.Attribute and are meant to be used in a different way to our other classes. To provide information about our data.
A commonly used attribute in C# is the [Obsolete] tag which you can use to give a warning to developers when one of your methods should no longer be used, mostly likely because it’s been replaced with something different. Unity uses this frequently to let us know when some part of their API should no longer be used.
Other uses of attributes can include adding tags to define when methods are called, like only calling certain functions when we are debugging so we don’t slowly down our program in the version we actually publish. C# also has their own form of serialisation [Serializable] that can be used to serialise data but it’s different to how Unity serialises things which is why unity has their own.
Unity makes use of attributes a lot within their engine, a lot of the time to make changes in the inspector. For instance, you can use [Range(0.0, 1.0)] property to limit what value you can apply to a variable in the inspector. And of course, coming back to the point of this article we can use the attribute SerializeField to tell Unity to serialize our private variables, so they become visible in the inspector.
We can also use multiple attributes together, so if we wanted our max health variable from before to only be within a certain range but still visible in the inspector, we can do that as well.
[Range(1, 100)]
[SerializeField]
private float _maxHealth = 100;
To summarise we can use SerializeField attribute to make our private variables visible in the inspector giving us the chance to easily tweak values without changing anything in code, whilst still gaining all the benefits of using information hiding.
SerializeField is just one attribute of many in Unity that can aid in our development, and knowing that attributes are nothing more than C# classes, we can easily come up with our own to help us out in anywhere that we need.
Further Reading
- https://docs.unity3d.com/ScriptReference/SerializeField.html
- https://docs.unity3d.com/Manual/script-Serialization-BuiltInUse.html
- https://blogs.unity3d.com/2014/06/24/serialization-in-unity/
- https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/attributes/
- https://unity3d.college/2017/05/22/unity-attributes/
To read me more check out my blog at: www.gamedevunboxed.com or if you have any questions then feel free to message me @gamedevunboxed :)