Learn Unity Editor Scripting: Attributes [Part 1]
In this post I’ll show you how to use the attributes defined in Unity assemblies to change how Unity Editor interacts with your components. Attributes are versatile and easy to use. You don’t need to write any editor-specific code. You just need to annotate your C# fields and classes with attributes.
This article is part of a series in which I explain all the techniques for extending the Unity Editor. See the overview post here.
Prerequisite: You need to know C# programming and be familiar with Unity Editor to benefit most from this post.
There is an accompanying Unity project. I highly recommend downloading it and trying the topics as you read them here. Seeing the examples in action makes them stick to your brain.
Getting Started with the Project
Download the github project linked above. There are folders corresponding to different posts in this series. Each folder is the repository is the same project with additions from the previous post. So for this article which is part1 you should start with arena-0 and at the end of the post, if you make all changes as described, your project should look like arena-1.
The project is very simple and has just a few scripts. Run the project. You can use the arrow keys to move around and your goal is to clear the arena of obstacles. When all obstacles are cleared or the player falls off the arena, the game ends and there is a message in the console indicating that.
Attributes
Attributes in C# let you annotate different programming elements (fields, methods, classes, etc.) and query them using Reflection. Unity Editor uses them to allow easy modification for some common scenarios.
[SerializeField]
This attribute tell Unity that this field should be serialized with the component. Note that initially the fields in PlayerController
class are declared public
. That’s why Unity serializes them and the Inspector window shows them.
Let’s mark our field private
as they should be for better coding practices. This time the Inspector for PlayerController
shows no fields.
However declaring fields public
just so they show up in the Inspector is not the right thing to do. Let’s make these fields private
which makes our code cleaner. But now these fields don’t show in Inspector.
Adding the [SerializeField]
attribute will make Unity serialize the fields and show them in Inspector even though they are private
.
Now the Inspector window looks exactly as before.
[Serializable]
You might have noticed that the specialAbility
field wasn’t shown in the Inspector. Unity can only serialize custom classes that have the Serializable
attribute. The rules for what Unity can handle are explained here.
Let’s go ahead and annotate our SpecialAbility
class with [Serializable] attribute.
Now the Inspector will show the specialAbility
field and let’s us edit it!
[HideInInspector]
By default Unity shows all the serialized fields for each components. However, being serialized and being shown in Inspector are two different things.
being Serializable and matching the criteria for being serialized by Unity are prerequisites for being shown in Inspector. But we can hide some of those fields in Inspector for example if we want to set the values only from code.
Let’s add the HideInInspector
attribute to the mass
field.
Now the Inspector window will not show the mass field. Note that the field still gets serialized and the mass that is set at Edit time (for example from code in OnValidate) will be written to disk.
We however want to be able to change the mass from our PlayerController
inspector. It may seem redundant since we can directly change the mass in the RigidBody
component. Keeping everything in one place makes making modifications easier. You have less chance of accidentally messing up the level setup if you avoid the RigidBody
component altogether. So let’s remove the HideInInspector
from the field.
[Header]
We don’t have too many fields in this sample, but in larger scripts with more fields, it makes sense to group them so that we find them more easily. In our sample Color
and Texture
fields are cosmetic whereas the other fields affect the game play. Let’s group our fields into General
and Visual
using the [Header]
attribute.
Note that the header attribute takes a string
parameter which is the header title.
Now you should see the fields grouped in the Inspector.
[Tooltip]
You can add a tooltip text to any field in Inspector. Let’s go ahead and add tooltips to both our color
and texture
fields.
Now if you hover your mouse over the label for these fields, you will see the tooltip for it.
[DisallowMultipleComponent]
Currently we could mistakenly add two PlayerController
components to a single GameObject.
We can add the [DisallowMultipleComponent]
attribute to our PlayerController
class.
Now Unity Editor will not allow us to add the duplicate component and shows us an error message instead.
Note that it is still possible to add duplicate components from code. Only adding it through the Editor UI is prohibited.
[Space]
We can add extra vertical empty space between fields to further separate them. Let’s add a 10 pixel space before the SpecialAbility
field.
And here is how the Inspector looks like after:
[TextArea]
By default the Inspector shows a single line text box for string
fields. In our GameManager
components, we want a longer text for the intro
text. This is the text that shows in the middle of the screen when the level starts and explains to the user what they should do.
By adding the [TextArea]
attribute to that field, we get a larger text area in the inspector window.
[Range]
mass
, speed
and size
are all float
fields. Often we want to limit these values to a certain range. the [Range]
attribute helps us with that.
Now in addition of the default text field, we can select the value from a slider. Range
also works with int
fields.
Conclusion
We went through some of the more common attributes for modifying the Inspector window and how the Unity Editor handles our classes. All we needed to do was adding attributes to our existing code.
There are many more attributes that Unity Editor understands by default. You can see them here on the left panel.
Attributes are very flexible. In fact, we can make our own custom attributes and use them in our Editor Code (in Property Drawers and Custom Inspectors and Editor Windows) which we will learn about later on!
Next
If you have any questions and suggestions about this post, feel free to leave a comment.
Follow me to get notified of my new posts. I am an indie game developer and regularly write tutorials, tips and tricks and stories about game dev, programming and Unity.
If you find this tutorial useful, please support me on Patreon. It takes a good amount of time to write these tutorials and your support will keep me going. Thank you!
Next we will learn how to create Property Drawer. They let us write code to show our own GUI in Inspector window for our custom data types or certain fields in our components.