# Technical Documentation: dbrizov/NaughtyAttributes

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/dbrizov/NaughtyAttributes)

### Overview (`README.md`)

# NaughtyAttributes
[](https://unity3d.com/get-unity/download)
[](https://openupm.com/packages/com.dbrizov.naughtyattributes/)
[](https://github.com/dbrizov/NaughtyAttributes/blob/master/LICENSE)

NaughtyAttributes is an extension for the Unity Inspector.

It expands the range of attributes that Unity provides so that you can create powerful inspectors without the need of custom editors or property drawers. It also provides attributes that can be applied to non-serialized fields or functions.

Most of the attributes are implemented using Unity's `CustomPropertyDrawer`, so they will work in your custom editors.
The attributes that won't work in your custom editors are the meta attributes and some drawer attributes such as
`ReorderableList`, `Button`, `ShowNonSerializedField` and `ShowNativeProperty`.
If you want all of the attributes to work in your custom editors, however, you must inherit from `NaughtyInspector` and use the `NaughtyEditorGUI.PropertyField_Layout` function instead of `EditorGUILayout.PropertyField`.

**[Documentation](https://unity.naughtyattributes.com/)**

## Installation

> NaughtyAttributes requires **2022.3** or later versions.

1. The package is available on the [openupm registry](https://openupm.com). You can install it via [openupm-cli](https://github.com/openupm/openupm-cli).
```
openupm add com.dbrizov.naughtyattributes
```
2. You can also install via git url by adding this entry in your **manifest.json**
```
"com.dbrizov.naughtyattributes": "https://github.com/dbrizov/NaughtyAttributes.git#upm"
```
3. You can also download it from the [Asset Store](https://assetstore.unity.com/packages/tools/utilities/naughtyattributes-129996)

# Overview

## Special Attributes

### AllowNesting
This attribute must be used in some cases when you want meta attributes to work inside serializable nested structs or classes.
You can check in which cases you need to use it [here](https://naughtyattributes.com/attributes/special_attributes/allow_nesting.html).

```csharp
public class NaughtyComponent : MonoBehaviour
{
    public MyStruct myStruct;
}

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

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

## Drawer Attributes
Provide special draw options to serialized fields.
A field can have only one DrawerAttribute. If a field has more than one, only the bottom one will be used.

### AnimatorParam
Select an Animator paramater via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	public Animator someAnimator;

	[AnimatorParam("someAnimator")]
	public int paramHash;

	[AnimatorParam("someAnimator")]
	public string paramName;
}
```



### Button
A method can be marked as a button. A button appears in the inspector and executes the method if clicked.
Works both with instance and static methods.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Button]
	private void MethodOne() { }

	[Button("Button Text")]
	private void MethodTwo() { }
}
```



### CurveRange
Set bounds and modify curve color for AnimationCurves

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

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

	[CurveRange(0, 0, 5, 5, EColor.Red)]
	public AnimationCurve curve2;
}
```



### Dropdown
Provides an interface for dropdown value selection.

```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 };

	private List<string> StringValues { get { return new List<string>() { "A", "B", "C", "D", "E" }; } }

	private DropdownList<Vector3> GetVectorValues()
	{
		return new DropdownList<Vector3>()
		{
			{ "Right",   Vector3.right },
			{ "Left",    Vector3.left },
			{ "Up",      Vector3.up },
			{ "Down",    Vector3.down },
			{ "Forward", Vector3.forward },
			{ "Back",    Vector3.back }
		};
	}
}
```



### EnumFlags
Provides dropdown interface for setting enum flags.

```csharp
public enum Direction
{
	None = 0,
	Right = 1 << 0,
	Left = 1 << 1,
	Up = 1 << 2,
	Down = 1 << 3
}

public class NaughtyComponent : MonoBehaviour
{
	[EnumFlags]
	public Direction flags;
}
```



### Expandable
Make scriptable objects expandable.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Expandable]
	public ScriptableObject scriptableObject;
}
```



### HorizontalLine

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[HorizontalLine(color: EColor.Red)]
	public int red;

	[HorizontalLine(color: EColor.Green)]
	public int green;

	[HorizontalLine(color: EColor.Blue)]
	public int blue;
}
```



### InfoBox
Used for providing additional information.

```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;

	[InfoBox("This is my vector", EInfoBoxType.Error)]
	public Vector3 myVector;
}
```



### InputAxis
Select an input axis via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[InputAxis]
	public string inputAxis;
}
```



### Layer
Select a layer via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Layer]
	public string layerName;

	[Layer]
	public int layerIndex;
}
```



### MinMaxSlider
A double slider. The **min value** is saved to the **X** property, and the **max value** is saved to the **Y** property of a **Vector2** field.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[MinMaxSlider(0.0f, 100.0f)]
	public Vector2 minMaxSlider;
}
```



### ProgressBar
```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ProgressBar("Health", 300, EColor.Red)]
	public int health = 250;

	[ProgressBar("Mana", 100, EColor.Blue)]
	public int mana = 25;

	[ProgressBar("Stamina", 200, EColor.Green)]
	public int stamina = 150;
}
```



### ReorderableList
Provides array type fields with an interface for easy reordering of elements.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ReorderableList]
	public int[] intArray;

	[ReorderableList]
	public List<float> floatArray;
}
```



### ResizableTextArea
A resizable text area where you can see the whole text.
Unlike Unity's **Multiline** and **TextArea** attributes where you can see only 3 rows of a given text, and in order to see it or modify it you have to manually scroll down to the desired row.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ResizableTextArea]
	public string resizableTextArea;
}
```



### Scene
Select a scene from the build settings via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Scene]
	public string bootScene; // scene name

	[Scene]
	public int tutorialScene; // scene index
}
```



### ShowAssetPreview
Shows the texture preview of a given asset (Sprite, Prefab...).

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ShowAssetPreview]
	public Sprite sprite;

	[ShowAssetPreview(128, 128)]
	public GameObject prefab;
}
```



### ShowNativeProperty
Shows native C# properties in the inspector.
All native properties are displayed at the bottom of the inspector after the non-serialized fields and before the method buttons.
It supports only certain types **(bool, int, long, float, double, string, Vector2, Vector3, Vector4, Color, Bounds, Rect, UnityEngine.Object)**.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	public List<Transform> transforms;

	[ShowNativeProperty]
	public int TransformsCount => transforms.Count;
}
```



### ShowNonSerializedField
Shows non-serialized fields in the inspector.
All non-serialized fields are displayed at the bottom of the inspector before the method buttons.
Keep in mind that if you change a non-static non-serialized field in the code - the value in the inspector will be updated after you press **Play** in the editor.
There is no such issue with static non-serialized fields because their values are updated at compile time.
It supports only certain types **(bool, int, long, float, double, string, Vector2, Vector3, Vector4, Color, Bounds, Rect, UnityEngine.Object)**.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ShowNonSerializedField]
	private int myInt = 10;

	[ShowNonSerializedField]
	private const float PI = 3.14159f;

	[ShowNonSerializedField]
	private static readonly Vector3 CONST_VECTOR = Vector3.one;
}
```



### SortingLayer
Select a sorting layer via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[SortingLayer]
	public string layerName;

	[SortingLayer]
	public int layerId;
}
```



### Tag
Select a tag via dropdown interface.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Tag]
	public string tagField;
}
```



## Meta Attributes
Give the fields meta data. A field can have more than one meta attributes.

### BoxGroup
Surrounds grouped fields with a box.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[BoxGroup("Integers")]
	public int firstInt;
	[BoxGroup("Integers")]
	public int secondInt;

	[BoxGroup("Floats")]
	public float firstFloat;
	[BoxGroup("Floats")]
	public float secondFloat;
}
```



### Foldout
Makes a foldout group.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Foldout("Integers")]
	public int firstInt;
	[Foldout("Integers")]
	public int secondInt;
}
```



### EnableIf / DisableIf
```csharp
public class NaughtyComponent : MonoBehaviour
{
	public bool enableMyInt;

	[EnableIf("enableMyInt")]
	public int myInt;

	[EnableIf("Enabled")]
	public float myFloat;

	[EnableIf("NotEnabled")]
	public Vector3 myVector;

	public bool Enabled() { return true; }

	public bool NotEnabled => false;
}
```



You can have more than one condition.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	public bool flag0;
	public bool flag1;

	[EnableIf(EConditionOperator.And, "flag0", "flag1")]
	public int enabledIfAll;

	[EnableIf(EConditionOperator.Or, "flag0", "flag1")]
	public int enabledIfAny;
}
```

### ShowIf / HideIf
```csharp
public class NaughtyComponent : MonoBehaviour
{
	public bool showInt;

	[ShowIf("showInt")]
	public int myInt;

	[ShowIf("AlwaysShow")]
	public float myFloat;

	[ShowIf("NeverShow")]
	public Vector3 myVector;

	public bool AlwaysShow() { return true; }

	public bool NeverShow => false;
}
```



You can have more than one condition.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	public bool flag0;
	public bool flag1;

	[ShowIf(EConditionOperator.And, "flag0", "flag1")]
	public int showIfAll;

	[ShowIf(EConditionOperator.Or, "flag0", "flag1")]
	public int showIfAny;
}
```

### Label
Override default field label.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Label("Short Name")]
	public string veryVeryLongName;

	[Label("RGB")]
	public Vector3 vectorXYZ;
}
```



### OnValueChanged
Detects a value change and executes a callback.
Keep in mind that the event is detected only when the value is changed from the inspector.
If you want a runtime event, you should probably use an event/delegate and subscribe to it.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[OnValueChanged("OnValueChangedCallback")]
	public int myInt;

	private void OnValueChangedCallback()
	{
		Debug.Log(myInt);
	}
}
```

### ReadOnly
Make a field read only.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[ReadOnly]
	public Vector3 forwardVector = Vector3.forward;
}
```



## Validator Attributes
Used for validating the fields. A field can have infinite number of validator attributes.

### MinValue / MaxValue
Clamps integer and float fields. The MinValue/MaxValue attributes can accept either a constant numeric value (e.g. 0, 1.5f) or the name of another field, property, or a parameterless function that returns a numeric value — use nameof(...) to reference members safely. When a name is provided, the referenced member is evaluated to obtain the min/max value at edit-time/runtime.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[MinValue(0), MaxValue(10)]
	public int myInt;

	[MinValue(0.0f)]
	public float myFloat;

	[MinValue("minFloat"), MaxValue("maxFloat")]
	public float myFloatThroughFieldName;

	[MinValue(nameof(minFloatProperty)), MaxValue(nameof(maxFloatProperty))]
	public float myFloatThroughPropertyName;

	private float minFloat = -1;
	private float maxFloat = 1;

	private float minFloatProperty => minFloat;
	private float maxFloatProperty => maxFloat;
}
```



### Required
Used to remind the developer that a given reference type field is required.

```csharp
public class NaughtyComponent : MonoBehaviour
{
	[Required]
	public Transform myTransform;

	[Required("Custom required text")]
	public GameObject myGameObject;
}
```



### RequiredType
Used on game objects or components.
When used on a game object, it checks if the game object has a component of the required type.
When used on a component, it checks if the game object it is attached to has a component of the required type.

```csharp
public class NaughtyComponent : MonoBehaviour
{
    [RequiredType(typeof(Rigidbody))]
    public GameObject gameObjectMustHaveRigidbody;

    [RequiredType(typeof(Rigidbody))]
    public Transform transformMustHaveRigidbody;

    [RequiredType(typeof(IRequiredTypeTestInterface))]
    public GameObject gameObjectMustHaveInterface;

    [RequiredType(typeof(RequiredTypeTestTestObject))]
    public GameObject gameObjectMustHaveComponent;

    [RequiredType(showInfoMessageWhenEmpty: false, typeof(IRequiredTypeTestInterface))]
    public GameObject shouldNotShowInfoMessageWhenEmpty;

    [RequiredType(typeof(IRequiredTypeTestInterface), typeof(IRequiredTypeTestInterface2))]
    public GameObject gameObjectMustHaveMultipleType;

    [RequiredType(typeof(RequiredTypeTestTestObject))]
    public RequiredTypeTest componentMustHaveAnotherComponent;
}
```



### ValidateInput
The most powerful ValidatorAttribute.

```csharp
public class _NaughtyComponent : MonoBehaviour
{
	[ValidateInput("IsNotNull")]
	public Transform myTransform;

	[ValidateInput("IsGreaterThanZero", "myInteger must be greater than zero")]
	public int myInt;

	private bool IsNotNull(Transform tr)
	{
		return tr != null;
	}

	private bool IsGreaterThanZero(int value)
	{
		return value > 0;
	}
}
```

---

### Sphinx Src Credits (`docs/sphinx/src/credits.rst`)

.. _label-credits:

Credits
=======
NaughtyAttributes is distributed under the MIT License. The assets this documentation site uses are credited below.

Unity trademarks
----------------
Unity and the Unity logo are trademarks or registered trademarks of Unity Technologies. They are used here only
to identify the engine these docs are for. NaughtyAttributes is not affiliated with, endorsed by, or sponsored by
Unity Technologies.

Fonts
-----
`Inter <https://github.com/rsms/inter>`_ — Copyright © 2016 The Inter Project Authors.

`JetBrains Mono <https://github.com/JetBrains/JetBrainsMono>`_ — Copyright © 2020 The JetBrains Mono Project Authors.

Both are used unmodified under the `SIL Open Font License, Version 1.1 <https://scripts.sil.org/OFL>`_.
The full license text ships beside the font files, at ``_static/css/fonts/LICENSE.txt``.

Stylesheet
----------
The theme overrides in ``_static/css/custom.css`` are adapted from the
`Godot Engine documentation <https://github.com/godotengine/godot-docs>`_, which is licensed under the
`Creative Commons Attribution 3.0 Unported License <https://creativecommons.org/licenses/by/3.0/>`_.

---

### Sphinx Src Index (`docs/sphinx/src/index.rst`)

Introduction
============
NaughtyAttributes is an open-source extension for the Unity Inspector.

It expands the range of attributes that Unity provides so that you can create powerful inspectors without the need of custom editors or property drawers.
It also provides attributes that can be applied to non-serialized fields or functions.

.. note::
    Most of the attributes are implemented using Unity's ``CustomPropertyDrawer``, so they will work in your custom editors.
    The attributes that won't work in your custom editors are the :ref:`label-meta-attributes` and some :ref:`label-drawer-attributes`
    such as :ref:`label-reorderable-list`, :ref:`label-button`, :ref:`label-show-non-serialized-field` and :ref:`label-show-native-property`.
    If you want all of the attributes to work in your custom editors, however,
    you must inherit from ``NaughtyInspector`` and use the ``NaughtyEditorGUI.PropertyField_Layout`` function instead of ``EditorGUILayout.PropertyField``.

Contribute
----------
If you want to contribute you can visit the `GitHub Repo <https://github.com/dbrizov/NaughtyAttributes>`_ and give me pull requests.
The project is using ``CRLF`` and ``Spaces`` instead of ``Tabs``. It's a must that you respect the coding standard.

Donation
--------
I am developing the project in my free time. If you like it you can support me by donating.

- `PayPal <https://paypal.me/dbrizov>`_
- `Buy Me A Coffee <https://www.buymeacoffee.com/dbrizov>`_


.. toctree::
    :maxdepth: 1
    :caption: General
    :name: sec-general

    general/installation

.. toctree::
    :maxdepth: 1
    :caption: Attributes
    :name: sec-attributes

    attributes/decorator_attributes/index
    attributes/drawer_attributes/index
    attributes/meta_attributes/index
    attributes/validator_attributes/index
    attributes/special_attributes/index

.. toctree::
    :maxdepth: 1
    :caption: About
    :name: sec-about

    credits

---

###  Static Css Fonts LICENSE (`docs/_static/css/fonts/LICENSE.txt`)

The font files in this directory are redistributed unmodified from their
upstream releases. Both are licensed under the SIL Open Font License,
Version 1.1, the full text of which follows.

Inter
    Inter-Regular.woff2, Inter-Italic.woff2, Inter-Bold.woff2, Inter-BoldItalic.woff2
    Version 4.001 (release v4.1)
    Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)

JetBrains Mono
    JetBrainsMono-Regular.woff2, JetBrainsMono-Medium.woff2
    Version 2.242 (release v2.242)
    Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)

-----------------------------------------------------------------------

SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION AND CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

---

### Sphinx Src General Installation (`docs/sphinx/src/general/installation.rst`)

Installation
============
.. note::
    NaughtyAttributes requires **Unity 2022.3** or later versions.

1. The package is available on the `openupm registry <https://openupm.com>`_. You can install it via `openupm-cli <https://github.com/openupm/openupm-cli>`_::

    openupm add com.dbrizov.naughtyattributes

2. You can also install via git url by adding this entry in your ``manifest.json``::

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

3. You can also download it from the `Asset Store <https://assetstore.unity.com/packages/tools/utilities/naughtyattributes-129996>`_

---

### Sphinx Src Attributes Decorator Attributes Horizontal Line (`docs/sphinx/src/attributes/decorator_attributes/horizontal_line.rst`)

HorizontalLine
==============
Similar to Unity's ``Space`` attribute, but draws a horizontal line instead of an empty space.
You can control the hight (thickness) and color of the line::

    public class NaughtyComponent : MonoBehaviour
    {
        [HorizontalLine(color: EColor.Red)]
        public int red;

        [HorizontalLine(color: EColor.Green)]
        public int green;

        [HorizontalLine(color: EColor.Blue)]
        public int blue;
    }

.. image:: ../../../images/HorizontalLine_Inspector.png

---

### Sphinx Src Attributes Decorator Attributes Index (`docs/sphinx/src/attributes/decorator_attributes/index.rst`)

.. _label-decorator-attributes:

Decorator Attributes
====================
Decorator attributes draw additional GUI around a field, instead of replacing the way the field itself is drawn.

.. note::
    Unlike :ref:`label-drawer-attributes`, a ``field`` can have more than one decorator attribute,
    and can be combined with a drawer attribute.

.. toctree::
    :maxdepth: 1
    :name: toc-decorator-attributes

    horizontal_line
    info_box

---

### Sphinx Src Attributes Decorator Attributes Info Box (`docs/sphinx/src/attributes/decorator_attributes/info_box.rst`)

InfoBox
=======
Used to provide additional information::

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

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

        [InfoBox("This is my vector", EInfoBoxType.Error)]
        public Vector3 myVector;
    }

.. image:: ../../../images/InfoBox_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Animator Param (`docs/sphinx/src/attributes/drawer_attributes/animator_param.rst`)

AnimatorParam
=============
Select an Animator paramater via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        public Animator someAnimator;

        [AnimatorParam("someAnimator")]
        public int paramHash;

        [AnimatorParam("someAnimator")]
        public string paramName;
    }

.. image:: ../../../images/AnimatorParam_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Button (`docs/sphinx/src/attributes/drawer_attributes/button.rst`)

.. _label-button:

Button
======
A method can be marked as a button. A button appears in the inspector and executes the method if clicked.
Works both with instance and static methods.

.. warning::
    Doesn't work on methods that are nested inside serialized structs or classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [Button]
        private void MethodOne(int parameter = 0) { } // Works with default parameters

        [Button("Button Text")] // Specify button text
        private void MethodTwo() { }

        [Button(enabledMode: EButtonEnableMode.Editor)]
        private void EnabledInEditorOnly() { }

        [Button(enabledMode: EButtonEnableMode.Playmode)]
        private void EnabledInPlaymodeOnly() { }

        [Button] // When pressed and the target object is a MonoBehaviour, it will start the coroutine
        private IEnumerator SomeCoroutine() { }
    }

.. image:: ../../../images/Button_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Curve Range (`docs/sphinx/src/attributes/drawer_attributes/curve_range.rst`)

CurveRange
==========
Can limit the ``x`` and ``y`` values of an animation curve, and/or change the color of the curve in the inspector::

    public class NaughtyComponent : MonoBehaviour
    {
        [CurveRange(-1, -1, 1, 1)] // min.x = -1, min.y = -1, max.x = 1, max.y = 1
        public AnimationCurve curve;
        
        [CurveRange(EColor.Orange)]
        public AnimationCurve curve1;
        
        [CurveRange(0, 0, 5, 5, EColor.Red)]
        public AnimationCurve curve2;
    }

.. image:: ../../../images/CurveRange_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Dropdown (`docs/sphinx/src/attributes/drawer_attributes/dropdown.rst`)

Dropdown
========
Provides an interface for dropdown value selection.
The values of the dropdown can be provided by a ``field``, ``property`` or ``function``.

.. warning::
    When nested inside a **struct** the value of the dropdown doesn't update.
    This is because the value of the parent struct is updated via reflection.
    In order for the value to be updated the struct needs to be **boxed** and then **unboxed**.
    The sctruct is already passed as an object (boxed) to the dropdown drawer, but unfortunately in order
    to unbox it I need to know the compile-time type of the struct, and I don't.
    Nesting inside a **class** works as expected.

::

    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 };

        private List<string> StringValues { get { return new List<string>() { "A", "B", "C", "D", "E" }; } }

        private DropdownList<Vector3> GetVectorValues()
        {
            return new DropdownList<Vector3>()
            {
                { "Right",   Vector3.right },
                { "Left",    Vector3.left },
                { "Up",      Vector3.up },
                { "Down",    Vector3.down },
                { "Forward", Vector3.forward },
                { "Back",    Vector3.back }
            };
        }
    }

.. image:: ../../../images/Dropdown_Inspector.gif

---

### Sphinx Src Attributes Drawer Attributes Enum Flags (`docs/sphinx/src/attributes/drawer_attributes/enum_flags.rst`)

EnumFlags
=========
Provides a dropdown interface for setting enum flags::

    public enum Direction
    {
        None = 0,
        Right = 1 << 0,
        Left = 1 << 1,
        Up = 1 << 2,
        Down = 1 << 3
    }

    public class NaughtyComponent : MonoBehaviour
    {
        [EnumFlags]
        public Direction flags;
    }

.. image:: ../../../images/EnumFlags_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Expandable (`docs/sphinx/src/attributes/drawer_attributes/expandable.rst`)

Expandable
==========
Make scriptable objects expandable::

    public class NaughtyComponent : MonoBehaviour
    {
        [Expandable]
        public ScriptableObject scriptableObject;
    }

.. image:: ../../../images/Expandable_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Index (`docs/sphinx/src/attributes/drawer_attributes/index.rst`)

.. _label-drawer-attributes:

Drawer Attributes
=================
Drawer attributes provide special draw options for the Unity Inspector.
They can be applied to serialized, and non-serialized fields, native C# properties, and functions.

.. note::
    A ``field``, ``property`` or ``function`` can have only one drawer attribute.

.. toctree::
    :maxdepth: 1
    :name: toc-drawer-attributes

    animator_param
    button
    curve_range
    dropdown
    enum_flags
    expandable
    input_axis
    layer
    min_max_slider
    progress_bar
    reorderable_list
    resizable_text_area
    scene
    show_asset_preview
    show_native_property
    show_non_serialized_field
    sorting_layer
    tag

---

### Sphinx Src Attributes Drawer Attributes Input Axis (`docs/sphinx/src/attributes/drawer_attributes/input_axis.rst`)

InputAxis
=========
Select an input axis via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        [InputAxis]
        public string inputAxis;
    }

.. image:: ../../../images/InputAxis_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Layer (`docs/sphinx/src/attributes/drawer_attributes/layer.rst`)

Layer
=====
Select a layer via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        [Layer]
        public string layerName;

        [Layer]
        public int layerIndex;
    }

.. image:: ../../../images/Layer_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Min Max Slider (`docs/sphinx/src/attributes/drawer_attributes/min_max_slider.rst`)

.. _label-min-max-slider:

MinMaxSlider
============
A double slider.
The **min value** is saved to the ``x`` property, and the **max value** is saved to the ``y`` property of a ``Vector2`` or a ``Vector2Int`` field::

    public class NaughtyComponent : MonoBehaviour
    {
        [MinMaxSlider(0.0f, 100.0f)]
        public Vector2 minMaxSlider;
    }

.. image:: ../../../images/MinMaxSlider_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Progress Bar (`docs/sphinx/src/attributes/drawer_attributes/progress_bar.rst`)

ProgressBar
===========
Draws a progress bar. Can be applied to an ``int`` or a ``float``::

    public class NaughtyComponent : MonoBehaviour
    {
        [ProgressBar("Health", 300, EColor.Red)]
        public int health = 250;

        [ProgressBar("Mana", 100, EColor.Blue)]
        public int mana = 25;

        [ProgressBar("Stamina", "maxStamina", EColor.Green)] // Dynamic max value constructor
        public int stamina = 150;

        public int maxStamina = 200;
    }

.. image:: ../../../images/ProgressBar_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Reorderable List (`docs/sphinx/src/attributes/drawer_attributes/reorderable_list.rst`)

.. _label-reorderable-list:

ReorderableList
===============
Provides array type fields with an interface for easy reordering of elements.
As of **Unity 2020.2.x** all lists are reorderable by default, so you no longer have to use this attribute.

.. warning::
    Doesn't work on lists that are nested inside serialized structs of classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [ReorderableList]
        public int[] intArray;

        [ReorderableList]
        public List<float> floatArray;
    }

.. image:: ../../../images/ReorderableList_Inspector.gif

---

### Sphinx Src Attributes Drawer Attributes Resizable Text Area (`docs/sphinx/src/attributes/drawer_attributes/resizable_text_area.rst`)

ResizableTextArea
=================
A resizable text area where you can see the whole text.
Unlike Unity's ``Multiline`` or ``TextArea`` attributes where you can see only 3 rows of a given text,
and in order to see it or modify it you have to manually scroll down to the desired row::

    public class NaughtyComponent : MonoBehaviour
    {
        [ResizableTextArea]
        public string resizableTextArea;
    }

.. image:: ../../../images/ResizableTextArea_Inspector.gif

---

### Sphinx Src Attributes Drawer Attributes Scene (`docs/sphinx/src/attributes/drawer_attributes/scene.rst`)

Scene
=====
Select a scene from the build settings via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        [Scene]
        public string bootScene; // scene name

        [Scene]
        public int tutorialScene; // scene index
    }

.. image:: ../../../images/Scene_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Show Asset Preview (`docs/sphinx/src/attributes/drawer_attributes/show_asset_preview.rst`)

ShowAssetPreview
================
Shows the texture preview of a given asset (Sprite, Prefab...)::

    public class NaughtyComponent : MonoBehaviour
    {
        [ShowAssetPreview]
        public Sprite sprite;

        [ShowAssetPreview(128, 128)]
        public GameObject prefab;
    }

.. image:: ../../../images/ShowAssetPreview_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Show Native Property (`docs/sphinx/src/attributes/drawer_attributes/show_native_property.rst`)

.. _label-show-native-property:

ShowNativeProperty
==================
Shows native C# properties in the inspector.
It supports only certain types ``bool``, ``short``, ``ushort``, ``int``, ``uint``, ``long``, ``ulong``, ``float``, ``double``, ``string``,
``Vector2``, ``Vector3``, ``Vector4``, ``Vector2Int``, ``Vector3Int``, ``Color``, ``Bounds``, ``Rect``, ``RectInt``, ``UnityEngine.Object``.

.. warning::
    Doesn't work on properties that are nested inside serialized structs of classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        public List<Transform> transforms;

        [ShowNativeProperty]
        public int TransformsCount => transforms.Count;
    }

.. image:: ../../../images/ShowNativeProperty_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Show Non Serialized Field (`docs/sphinx/src/attributes/drawer_attributes/show_non_serialized_field.rst`)

.. _label-show-non-serialized-field:

ShowNonSerializedField
======================
Shows non-serialized fields in the inspector.
Keep in mind that if you change a non-static non-serialized field in the code - the value in the inspector will be updated after you press **Play** in the editor.
There is no such issue with static non-serialized fields because their values are updated at compile-time.
It supports only certain types ``bool``, ``short``, ``ushort``, ``int``, ``uint``, ``long``, ``ulong``, ``float``, ``double``, ``string``,
``Vector2``, ``Vector3``, ``Vector4``, ``Vector2Int``, ``Vector3Int``, ``Color``, ``Bounds``, ``Rect``, ``RectInt``, ``UnityEngine.Object``.

.. warning::
    Doesn't work on non-serialized fields that are nested inside serialized structs of classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [ShowNonSerializedField]
        private int myInt = 10;

        [ShowNonSerializedField]
        private const float PI = 3.14159f;

        [ShowNonSerializedField]
        private static readonly Vector3 CONST_VECTOR = Vector3.one;
    }

.. image:: ../../../images/ShowNonSerializedField_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Sorting Layer (`docs/sphinx/src/attributes/drawer_attributes/sorting_layer.rst`)

SortingLayer
============
Select a sorting layer via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        [SortingLayer]
        public string layerName;

        [SortingLayer]
        public int layerId;
    }

.. image:: ../../../images/SortingLayer_Inspector.png

---

### Sphinx Src Attributes Drawer Attributes Tag (`docs/sphinx/src/attributes/drawer_attributes/tag.rst`)

Tag
===
Select a tag via dropdown interface::

    public class NaughtyComponent : MonoBehaviour
    {
        [Tag]
        public string tagField;
    }

.. image:: ../../../images/Tag_Inspector.png

---

### Sphinx Src Attributes Meta Attributes Box Group (`docs/sphinx/src/attributes/meta_attributes/box_group.rst`)

BoxGroup
========
Can be used to group serialized fields.

.. warning::
    Doesn't work on serialized fields that are nested inside serialized structs of classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [BoxGroup("Integers")]
        public int firstInt;
        [BoxGroup("Integers")]
        public int secondInt;

        [BoxGroup("Floats")]
        public float firstFloat;
        [BoxGroup("Floats")]
        public float secondFloat;
    }

.. image:: ../../../images/BoxGroup_Inspector.png

---

### Sphinx Src Attributes Meta Attributes Enable Disable If (`docs/sphinx/src/attributes/meta_attributes/enable_disable_if.rst`)

.. _label-enable-disable-if:

EnableIf / DisableIf
====================
Can be used to make serialized fields or buttons ``readonly`` based on some condition.
The condition can be a ``field``, ``property`` or ``function``.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        public bool enableMyInt;

        [EnableIf("enableMyInt")]
        public int myInt;

        [EnableIf("Enabled")]
        public float myFloat;

        [EnableIf("NotEnabled")]
        public Vector3 myVector;

        public bool Enabled() { return true; }

        public bool NotEnabled => false;
    }

.. image:: ../../../images/EnableIf_Inspector.gif

You can have more than one condition::

    public class NaughtyComponent : MonoBehaviour
    {
        public bool flag0;
        public bool flag1;

        [EnableIf(EConditionOperator.And, "flag0", "flag1")]
        public int enabledIfAll;

        [EnableIf(EConditionOperator.Or, "flag0", "flag1")]
        public int enabledIfAny;
    }

An enum value can also be used as a condition::

    public class NaughtyComponent : MonoBehaviour
    {
        public EMyEnum enumFlag;

        [EnableIf("enumFlag", EMyEnum.Case0)]
        public int enableIfEnum; // Will be enabled only if enumFlag == EMyEnum.Case0
    }

    public enum EMyEnum
    {
        Case0,
        Case1,
        Case2
    }

---

### Sphinx Src Attributes Meta Attributes Foldout (`docs/sphinx/src/attributes/meta_attributes/foldout.rst`)

Foldout
=======
Makes a foldout group.

.. warning::
    Doesn't work on serialized fields that are nested inside serialized structs of classes.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [Foldout("Integers")]
        public int firstInt;
        [Foldout("Integers")]
        public int secondInt;
    }

.. image:: ../../../images/Foldout_Inspector.gif

---

### Sphinx Src Attributes Meta Attributes Index (`docs/sphinx/src/attributes/meta_attributes/index.rst`)

.. _label-meta-attributes:

Meta Attributes
===============
Give fields or methods meta data. A field or method can have more than one meta attribute.

.. toctree::
    :maxdepth: 1
    :name: toc-meta-attributes

    box_group
    enable_disable_if
    foldout
    label
    on_value_changed
    read_only
    show_hide_if

---

### Sphinx Src Attributes Meta Attributes Label (`docs/sphinx/src/attributes/meta_attributes/label.rst`)

Label
=====
Override default field label.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [Label("Short Name")]
        public string veryVeryLongName;

        [Label("RGB")]
        public Vector3 vectorXYZ;
    }

.. image:: ../../../images/Label_Inspector.png

---

### Sphinx Src Attributes Meta Attributes On Value Changed (`docs/sphinx/src/attributes/meta_attributes/on_value_changed.rst`)

OnValueChanged
==============
Detects a value change and executes a callback.
Keep in mind that the event is detected only when the value is changed from the inspector.
If you want a runtime event, you should probably use an event/delegate and subscribe to it.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [OnValueChanged("OnValueChangedCallback")]
        public int myInt;

        private void OnValueChangedCallback()
        {
            Debug.Log(myInt);
        }
    }

---

### Sphinx Src Attributes Meta Attributes Read Only (`docs/sphinx/src/attributes/meta_attributes/read_only.rst`)

ReadOnly
========
Make a serialized field readonly

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [ReadOnly]
        public Vector3 forwardVector = Vector3.forward;
    }

.. image:: ../../../images/ReadOnly_Inspector.png

---

### Sphinx Src Attributes Meta Attributes Show Hide If (`docs/sphinx/src/attributes/meta_attributes/show_hide_if.rst`)

ShowIf / HideIf
===============
Can be used to show/hide serialized fields or buttons based on some condition.
The condition can be a ``field``, ``property`` or ``function``.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        public bool showInt;

        [ShowIf("showInt")]
        public int myInt;

        [ShowIf("AlwaysShow")]
        public float myFloat;

        [ShowIf("NeverShow")]
        public Vector3 myVector;

        public bool AlwaysShow() { return true; }

        public bool NeverShow => false;
    }

.. image:: ../../../images/ShowIf_Inspector.gif

You can have more than one condition::

    public class NaughtyComponent : MonoBehaviour
    {
        public bool flag0;
        public bool flag1;

        [ShowIf(EConditionOperator.And, "flag0", "flag1")]
        public int showIfAll;

        [ShowIf(EConditionOperator.Or, "flag0", "flag1")]
        public int showIfAny;
    }

An enum value can also be used as a condition::

    public class NaughtyComponent : MonoBehaviour
    {
        public EMyEnum enumFlag;

        [ShowIf("enumFlag", EMyEnum.Case0)]
        public int enableIfEnum; // Will be shown only if enumFlag == EMyEnum.Case0
    }

    public enum EMyEnum
    {
        Case0,
        Case1,
        Case2
    }

---

### Sphinx Src Attributes Special Attributes Allow Nesting (`docs/sphinx/src/attributes/special_attributes/allow_nesting.rst`)

.. _label-allow-nesting:

AllowNesting
============

By default :ref:`label-drawer-attributes` can be nested inside structs and classes.
:ref:`label-meta-attributes` and :ref:`label-validator-attributes`  however are not drawers and don't support nesting out of the box.
If you want to use :ref:`label-enable-disable-if` attributes inside structs for instance, you have to use the ``AllowNesting`` attribute like so::

    public class NaughtyComponent : MonoBehaviour
    {
        public MyStruct myStruct;
    }

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

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

.. note::
    The ``AllowNesting`` attribute is actually a drawer attribute. You can think of it as a ``DefaultDrawer`` attribute.
    All it does is draw the serialized field with its default drawer. This is a bit of a hack you see.
    The system is implemented in such a way that before a drawer's ``OnGUI`` function is called it applies the **meta** and **validator** attributes.
    In order to trigger this behavoir we need some kind of a drawer. The ``AllowNesting`` is that drawer.
    If for you are combining :ref:`label-enable-disable-if` with :ref:`label-min-max-slider` for instance,
    you don't have to put the ``AllowNesting`` attribute, because you already marked the serialized field with the ``MinMaxSlider`` drawer.

---

### Sphinx Src Attributes Special Attributes Index (`docs/sphinx/src/attributes/special_attributes/index.rst`)

Special Attributes
==================

.. toctree::
    :maxdepth: 1
    :name: toc-special-attributes

    allow_nesting

---

### Sphinx Src Attributes Validator Attributes Index (`docs/sphinx/src/attributes/validator_attributes/index.rst`)

.. _label-validator-attributes:

Validator Attributes
====================
Used for validating fields. A field can have infinite number of validator attributes.

.. toctree::
    :maxdepth: 1
    :name: toc-validator-attributes

    min_max_value
    required
    required_type
    validate_input

---

### Sphinx Src Attributes Validator Attributes Min Max Value (`docs/sphinx/src/attributes/validator_attributes/min_max_value.rst`)

MinValue / MaxValue
===================
Can be used to limit the range of variables.
Can be applied to ``int``, ``float``, ``Vector2``, ``Vector3``, ``Vector4``, ``Vector2Int``, ``Vector3Int``.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [MinValue(0), MaxValue(10)]
        public int myInt;

        [MinValue(0.0f)]
        public float myFloat;
    }

.. image:: ../../../images/MinValueMaxValue_Inspector.gif

---

### Sphinx Src Attributes Validator Attributes Required (`docs/sphinx/src/attributes/validator_attributes/required.rst`)

Required
========
Used to remind the user that a given reference type field is required.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [Required]
        public Transform myTransform;

        [Required("Custom required text")]
        public GameObject myGameObject;
    }

.. image:: ../../../images/Required_Inspector.png

---

### Sphinx Src Attributes Validator Attributes Required Type (`docs/sphinx/src/attributes/validator_attributes/required_type.rst`)

RequiredType
============
Used on game objects or components.
When used on a game object, it checks if the game object has a component of the required type.
When used on a component, it checks if the game object it is attached to has a component of the required type.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [RequiredType(typeof(Rigidbody))]
        public GameObject gameObjectMustHaveRigidbody;

        [RequiredType(typeof(Rigidbody))]
        public Transform transformMustHaveRigidbody;

        [RequiredType(typeof(IRequiredTypeTestInterface))]
        public GameObject gameObjectMustHaveInterface;

        [RequiredType(typeof(RequiredTypeTestTestObject))]
        public GameObject gameObjectMustHaveComponent;

        [RequiredType(showInfoMessageWhenEmpty: false, typeof(IRequiredTypeTestInterface))]
        public GameObject shouldNotShowInfoMessageWhenEmpty;

        [RequiredType(typeof(IRequiredTypeTestInterface), typeof(IRequiredTypeTestInterface2))]
        public GameObject gameObjectMustHaveMultipleType;

        [RequiredType(typeof(RequiredTypeTestTestObject))]
        public RequiredTypeTest componentMustHaveAnotherComponent;
    }

.. image:: ../../../images/RequiredType_Inspector.png

---

### Sphinx Src Attributes Validator Attributes Validate Input (`docs/sphinx/src/attributes/validator_attributes/validate_input.rst`)

ValidateInput
=============
The most powerful ValidatorAttribute.

.. note::
    If you want to use it on fields that are nested inside serialized structs or classes
    you need to use the :ref:`label-allow-nesting` attribute.

::

    public class NaughtyComponent : MonoBehaviour
    {
        [ValidateInput("IsNotNull")]
        public Transform myTransform;

        [ValidateInput("IsGreaterThanZero", "myInteger must be greater than zero")]
        public int myInt;

        private bool IsNotNull(Transform tr)
        {
            return tr != null;
        }

        private bool IsGreaterThanZero(int value)
        {
            return value > 0;
        }
    }

.. image:: ../../../images/ValidateInput_Inspector.png

---

### Sphinx Static Css Fonts LICENSE (`docs/sphinx/static/css/fonts/LICENSE.txt`)

The font files in this directory are redistributed unmodified from their
upstream releases. Both are licensed under the SIL Open Font License,
Version 1.1, the full text of which follows.

Inter
    Inter-Regular.woff2, Inter-Italic.woff2, Inter-Bold.woff2, Inter-BoldItalic.woff2
    Version 4.001 (release v4.1)
    Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)

JetBrains Mono
    JetBrainsMono-Regular.woff2, JetBrainsMono-Medium.woff2
    Version 2.242 (release v2.242)
    Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)

-----------------------------------------------------------------------

SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION AND CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

---

--- METRICS ---
- Files Extracted: 43
- Estimated Token Budget: ~13907 tokens
- Canonical Reference: https://codewiki.google/github.com/dbrizov/NaughtyAttributes
