Creating Custom Unity Attributes: ReadOnly
ReadOnly is a common name for an Attribute that makes a public/serialized field non-editable in the Unity Inspector, while still being visible.
Today’s Objective: Teach you how to create your own version of the ReadOnly Attribute for use in any Unity project.
NOTE: I’ve just started learning how to create my own custom Attributes very recently, so if you see any improvements that could be made, please let me know! :)
The ReadOnly Attribute:
The ReadOnly Attribute does what its name implies: makes a variable shown in the Unity Inspector read-only, meaning non-editable directly via the Inspector.
The Code:
First, I create a new C# script called “ReadOnlyAttribute”, and clear all the default code.
IMPORTANT: It is easy to miss when starting out, but when creating an Attribute, the class name must have the suffix “Attribute” on the end (“ReadOnlyAttribute”). This is how C# and Unity know to treat this as an Attribute.
Inside the new file, I’ve chosen to put all my Attribute classes inside a new Namespace called “CustomAttributes”. This is good practice when writing organized code.
Now create the class itself as a public class with name “ReadOnlyAttribute” and inheriting from Unity’s “PropertyAttribute” base class.
Also add an attribute above this attribute class to define how our ReadOnly attribute can be used.
AttributeUsage Parameters:
- Attribute Target (required): What types of definitions can this attribute be used on?
2. Allow Multiple (Optional): Controls if multiple of this attribute can be applied to the same target.
3. Inherited (Optional): If a base class has a variable/method/etc using this attribute, and another class derived from it, will the attribute be applied to the derived class too?
Since the ReadOnly attribute only needs to make the variable non-editable, it doesn’t require any more functionality here. Next we need to create a custom Property Drawer to do the functionality.
The ReadOnly Property Drawer:
Create a new class called “ReadOnlyPropertyDrawer”, and inherit from “UnityEditor.PropertyDrawer”.
IMPORTANT: This script must be placed within a folder called “Editor” in your project files, since it is only supposed to be used by the Unity Editor, and Unity recognizes all “Editor” folders as such.
Inside the class, override the OnGUI method.
- Disable the GUI for this property. This makes it non-editable.
- Create a Property Field for the variable the attribute is applying to. This draws the variable in the Inspector. Since we’re overriding OnGUI, without this, nothing appears.
3. Re-enable the GUI ready for any following elements.
The result:
Any field can be marked as Read-Only and become non-editable from the Inspector! A great way to display class data without allowing it to be accidentally edited.
Next:
In the next few posts, I’ll be trying out making some other useful attributes, getting more complex as we go.