Happy Friday! Hope you’ve had a splendid week. Today we are going to be discussing attributes. You likely have seen these before in C# scripts as little tags above sections of code. Most of the time in Unity, these tags are shown to change how certain things appear in the editor, but they can do much more than just that. Today we’ll go over:

  1. What Attributes Are and How to Use Them
  2. Overhauling Script Inspector Windows with Attributes
  3. 3rd Party Attributes and Creating Your Own Custom Attributes

And make sure you read to the end because I’ll be featuring an upcoming game from a U.S. based indie developer, The Wandering Band.



1. What Attributes Are and How to Use Them

Before we talk about attributes in the context of the Unity game engine, it is important that we talk about where attributes come from – C#. In C#, attributes are a way of associating metadata with sections of code, whether that be classes, methods, properties, etc.

Attributes by themselves only associate extra data with the code, so they don’t actually do anything. However, using concepts like reflection (a way for programming languages to look at the language itself and get information about it) we can scan for these attributes then perform some behavior.

But don’t worry about that too much right now, you don’t need to fully understand how attributes work in order to use them effectively.

To use an attribute, simply put the attribute name in square brackets immediately before the code you wish to apply the attribute to. For example, we can use the [HideInInspector] attribute to hide public variables from displaying in the Inspector window like this:

[HideInInspector]
public int hitCount;

In this case, the integer variable hitCount would still be available to other scripts due to the public access modifier, but the value would not show in the Unity Inspector window. Conversely, we can use the [SerializeField] attribute to show private values in the Inspector window:

[SerializeField]
private string itemDescription;

In the example above, we may want to provide the developers of our project with a larger text area to write a description for each item. We can simply do that by adding the [TextArea] attribute to the variable as such:

[SerializeField]
[TextArea]
private string itemDescription;

Note that you can declare multiple attributes separated by commas in a single set of square brackets like: [SerializeField, TextArea] however I usually separate them out in their own set of brackets.

The result of adding the aforementioned attributes to a script would look like this in the inspector:

Note how we do not see the public hitCount variable, yet we do see the private itemDescription variable represented as a text area.

Another key concept of attributes is that we can pass values into them similar to methods. For example, with the [AddComponentMenu] attribute, we can specify where a specific class appears in the “Add Component” menu. For our Item class we could specify:

[AddComponentMenu("My Game Stuff/Item")]
public class Item : MonoBehaviour

Then when we go to the Add Component menu, you’ll see that the Item component appears under a folder called “My Game Stuff.” 

2. Overhauling Script Inspector Windows with Attributes

In last week’s Feature Friday, I mentioned that there was a way that you could customize the inspector views of your scripts to your liking. Well there is actually a much easier way to bring some level of customization to the inspector views of your scripts by using attributes.

I already showed you this a bit above by showing and hiding properties, but there are more useful ones to know. Here are some of my favorites:

The [Header] attribute puts a label above properties in the Inspector. This is useful when you have several related properties. So if we had a bunch of statistics for our item, we could separate that out in the inspector from store properties.

[Header("Statistics")] 
public int hitCount;
public int damage;
public int weight;

[Header("Store Properties")] 
public int cost;
[SerializeField] 
[TextArea] 
private string itemDescription;

The above code would result with this in the inspector:

A simple one we could add is the [Space] attribute that just puts a little space in between the property and the one above – also great for organization.

An attribute I use all the time is the [Range] attribute. With this, you can specify the high and low values for a variable, then a slider appears in the inspector window for you to set the values. The code:

[Range(0, 10)]
public int damage;

Would look like this in the inspector:

The [Tooltip] attribute will display some information about a property when you hover your mouse over it in the Inspector.

Finally the [ContextMenu] attribute provides you a handy way to execute methods of a class from the inspector window. Just add the attribute as such:

[ContextMenu("Validate Item")]
private void ValidateItem() { /* Item Validation Code */ }

Then we can run this code, by selecting the “Validate Item” option in the menu on the component with the 3 vertical dots

But don’t forget, there are still a ton more attributes to add to your code. Check out the full Unity documentation for more examples: 

https://docs.unity3d.com/2020.1/Documentation/Manual/Attributes.html

3. 3rd Party Attributes and Creating Custom Attributes

Many 3rd party tools contain their own attributes to add functionality and flexibility to your code. One of the best 3rd party tools for extra attributes is the Odin inspector. The Odin inspector has dozens of extra attributes to add further customization to your Inspector windows.

One that I like is the [TableMatrix] attribute where you can display a 2D array as a grid right in the inspector!

You can also add buttons and toggle groups, much like you can in a full custom inspector, without the hassle of creating a full one yourself. I highly recommend you check out this tool if you don’t already have it:

https://assetstore.unity.com/packages/tools/utilities/odin-inspector-and-serializer-89041?aid=1101l9vRP

And of course if third party tools can create their own custom attributes, that means you can as well. Making them is pretty trivial, but accessing the data on them gets a bit more complicated as you have to use reflection to look at the types, properties, and methods to determine if a specific attribute is applied then execute said behavior.

If you’re up for it, here is the link to the C# documentation on how to create your own custom attributes:

https://docs.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes


Featured Unity Game of the Week: Airborne Kingdom

I first heard about this game on the Unity Behind the Game podcast. This game is made by a small team of just a few people and they are making something really cool. It is a combination city-builder and exploration game. In this game you build a city that is floating in the air and you need to explore around the world, by navigating your “Airborne Kingdom” to find resources to continue to grow. 

It’s set to come out in just about a month and you can learn more about it here:

https://www.airbornekingdom.com/

Or see a video of some gameplay here:


Let me know what some of your favorite uses of attributes are!

Anyways I hope you are all staying well, and as always, keep on creating!

-Johnny Thompson
Turbo Makes Games