# NaughtyAttributes: a Unity Inspector extension built entirely on attributes

> An MIT licensed package that adds dropdowns, buttons, validation and expandable objects to the default Unity inspector, with an honest list of where it stops working in custom editors.

**dbrizov/NaughtyAttributes** — Attribute Extensions for Unity

- Repository: https://github.com/dbrizov/NaughtyAttributes
- Website: https://unity.naughtyattributes.com/
- Stars: 5,220 · Forks: 505
- Language: C#
- License: MIT
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/dbrizov-naughtyattributes

## Attributes instead of custom editors, and why that is the trade

NaughtyAttributes extends the Unity Inspector using attributes. The README states the goal directly: expand the range of attributes Unity provides so you can create powerful inspectors without the need of custom editors or property drawers. It also handles attributes on non-serialized fields and on functions, which Unity's built-in system does not.

That is the whole thesis of the package, and it is a real trade rather than a free upgrade. A custom editor is unlimited in what it can draw and costs you a file, a lifecycle, and usually an OnValidate that fights with Undo and prefab overrides. An attribute costs one line at the declaration site and gives you a fixed set of behaviours. For the common cases, which are dropdowns and validation, the attribute wins by a wide margin.

Most of the attributes are implemented with Unity's `CustomPropertyDrawer`, which is what lets them work inside custom editors as well as the default one. The repository is dbrizov/NaughtyAttributes, 5213 stars, 501 forks, 127 open issues, MIT licensed, on `master`, last pushed on 2026-09-16. The tree is a full Unity project layout with `Assets/`, `Packages/` and `ProjectSettings/`, plus a `docs/` directory.

## Three installation routes, one of which is the Asset Store

Installation is a three-option list, and it covers the ways Unity developers actually acquire packages. The requirement is stated before the list: NaughtyAttributes requires Unity 2022.3 or later.

The first route is the openupm registry via the openupm-cli:

```bash
openupm add com.dbrizov.naughtyattributes
```

The second is a git URL added as an entry in your `manifest.json`, which pins to a branch called `upm` rather than `master`:

```json
"com.dbrizov.naughtyattributes": "https://github.com/dbrizov/NaughtyAttributes.git#upm"
```

The third is the Unity Asset Store. That is worth noting on its own, because the Asset Store route is a commercial channel and it means you can install this without touching a git URL or a registry at all, which is the path most likely to work in a locked-down studio environment.

The branch naming detail is the kind of thing that costs an afternoon if you get it wrong. The repository default branch is `master`, but the UPM manifest entry references `#upm`, so cloning and pointing at the default branch does not give you a package Unity can resolve.

## Dropdown attributes for the stringly-typed mistakes

The largest family of attributes replaces free-text inspector fields with a dropdown, and it is the clearest example of the value proposition. `[Dropdown]` accepts either a member name or a method name on the same component:

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Dropdown("intValues")]
	public int intValue;

	[Dropdown("StringValues")]
	public string stringValue;

	[Dropdown("GetVectorValues")]
	public Vector3 vectorValue;

	private int[] intValues = new int[] { 1, 2, 3, 4, 5 };
}
```

The domain-specific variants do the same job against Unity subsystems that are otherwise stringly typed. `[AnimatorParam]` takes an Animator field and offers its parameters, so you can pick from int paramHash or string paramName without leaving the inspector. `[InputAxis]` lists input axes, `[Layer]` lists physics layers, and `[SortingLayer]` was added later to do the same for sorting layers.

Then there is `[EnumFlags]`, which turns a flags enum into a multi-select dropdown, and `[CurveRange]`, which constrains an AnimationCurve to bounds and can recolour it:

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[CurveRange(-1, -1, 1, 1)]
	public AnimationCurve curve;

	[CurveRange(EColor.Orange)]
	public AnimationCurve curve1;
}
```

In practice these are the attributes that remove a class of bug. A typo in an animator parameter name is a null reference at runtime; a typo caught by a dropdown is impossible.

## Presentation attributes that need no data of their own

A second group is purely visual, and these are the ones that make an inspector feel designed rather than generated. `[InfoBox]` attaches a message to a field with a severity level, Normal, Warning or Error:

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[InfoBox("This is my int", EInfoBoxType.Normal)]
	public int myInt;

	[InfoBox("This is my float", EInfoBoxType.Warning)]
	public float myFloat;
}
```

`[HorizontalLine]` takes a colour and draws a separator, which sounds trivial until you have a thirty-field component. `[Button]` turns a method into a clickable button in the inspector, and the README notes it works on both instance and static methods, with an optional label string.

`[Expandable]` lets a ScriptableObject field be expanded inline instead of showing a single object reference, so you can edit a nested asset without losing your place in the inspector. Version 2.1.5 added an optional `IsReadonly` parameter to it, and also made `[ProgressBar]` draggable like a slider so you can set the value directly rather than typing it.

None of these touch your data model, which is exactly why they are cheap to adopt. A field that gains an InfoBox and a HorizontalLine still serializes identically.

## The custom editor caveat is the one to read twice

The README names its own limitation, and it is specific enough that you should not skim it. Most attributes work in custom editors because they are built on `CustomPropertyDrawer`. The ones that will not are the meta attributes, plus four drawer attributes specifically: `ReorderableList`, `Button`, `ShowNonSerializedField` and `ShowNativeProperty`.

The reason is architectural. Unity's custom editor drawing path does not route through whatever mechanism the meta attributes hook into, so if you have an existing custom editor, those attributes silently do nothing. The README gives the fix, and it has a cost: to get all of them working you must inherit from `NaughtyInspector` and call `NaughtyEditorGUI.PropertyField_Layout` in place of `EditorGUILayout.PropertyField`.

That is not a small change if you already have a large custom editor, since every property field call has to be replaced. The sensible approach is to use NaughtyAttributes on components that still use the default inspector, which is most of them, and not to attempt a retrofit of your heaviest custom editor unless you specifically need one of those four attributes.

There is also a nested-struct trap with a documented escape hatch. `[AllowNesting]` is required for meta attributes to work inside serializable nested structs or classes:

```csharp
[System.Serializable]
public struct MyStruct
{
    public bool enableFlag;

    [EnableIf("enableFlag")]
    [AllowNesting] // Because it's nested we need to explicitly allow nesting
    public int integer;
}
```

The comment in the README's own example is the whole explanation. Without it, the conditional attribute does nothing inside a nested type, and the failure is silence rather than an error.

## Version 2.1.5 raised the floor and 2.1.6 chased a Unity API

The release history is short and tells a clear story about maintenance. Version 2.1.4 came in February 2022 and added `[SortingLayer]`. Then a long gap, and version 2.1.5 in April 2026 did three things at once: it raised the minimum supported Unity version from 2019.4.x to 2022.3.x, added the `[RequiredType]` validator attribute, and improved `[Expandable]` and `[ProgressBar]` while adding Unity 6.4 support.

`[RequiredType]` is the interesting addition. Applied to a game object it checks whether that object has a component of the required type; applied to a component, it checks whether the game object the component sits on has one. That is a dependency assertion you would otherwise write by hand in OnValidate.

Version 2.1.6 in June 2026 is a single fix, and the shape of it is instructive: a compilation issue in Unity 6000.5 caused by a new `GetEntityId()` API. That is the maintenance profile of this package in one line. Nothing about NaughtyAttributes changes; Unity changes underneath it, and the author ships a patch.

Which means the real question when adopting is not whether the library is good, since for the scope it covers it clearly is, but whether your Unity version is one it has caught up with. The README badge and the release notes are the place to check.

## Conclusion

NaughtyAttributes is at its best on the plain inspector, on components and ScriptableObjects where a designer will be adjusting values and you would rather not write a custom editor for each one. The dropdown attributes for animators, layers, tags and sorting layers remove the stringly-typed mistakes that make a project annoying, and the validator attributes give you warnings without a runtime cost. The limitation the README is upfront about is custom editors: meta attributes and a handful of drawers will not work unless you inherit from NaughtyInspector and route your fields through its property field function, which is a real migration cost if you already have custom editors. Version 2.1.5 raised the floor to Unity 2022.3, so check that before upgrading an older project. Start by putting one dropdown attribute on an existing component and see whether the inspector change is enough to avoid a custom editor.

## FAQ

### What are attributes in Unity and how are they used?

An attribute in C# is metadata attached to a declaration, and Unity reads many of them to change how a field is drawn in the Inspector. NaughtyAttributes is a package of additional ones, so `[Dropdown("intValues")]` above a field turns a free-text inspector entry into a list of choices. Most of them are implemented with Unity's `CustomPropertyDrawer`, which is why they also work inside your own custom editors.

### Why isn't the Unity Inspector showing anything?

The most likely cause is that the field is inside a custom editor that draws properties itself. The README states that the meta attributes, plus `ReorderableList`, `Button`, `ShowNonSerializedField` and `ShowNativeProperty`, do not work in custom editors unless you inherit from `NaughtyInspector` and use `NaughtyEditorGUI.PropertyField_Layout`. A second common cause is a meta attribute inside a nested struct without `[AllowNesting]`, which fails silently.

### How do I install NaughtyAttributes in a Unity project?

Three routes are documented: add it from the openupm registry with `openupm add com.dbrizov.naughtyattributes`, add a git URL entry for `https://github.com/dbrizov/NaughtyAttributes.git#upm` to your `manifest.json`, or install it from the Unity Asset Store. Note the `#upm` branch in the git URL, which is not the repository's default branch, and that Unity 2022.3 or later is required.

### What is the minimum Unity version for NaughtyAttributes?

Unity 2022.3 or later. The README states that requirement, and version 2.1.5 made it official by raising the floor from 2019.4.x to 2022.3.x. Later releases added support for Unity 6.4 and fixed a compilation problem with Unity 6000.5.

## Sources

- [dbrizov/NaughtyAttributes on GitHub](https://github.com/dbrizov/NaughtyAttributes)
- [License: MIT](https://github.com/dbrizov/NaughtyAttributes/blob/master/LICENSE)
- [Project website](https://unity.naughtyattributes.com/)
- [README](https://github.com/dbrizov/NaughtyAttributes/blob/master/README.md)
- [Releases](https://github.com/dbrizov/NaughtyAttributes/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dbrizov-naughtyattributes
