2022-01-30 11:32:05 -05:00
# Tri Inspector [![Github license](https://img.shields.io/github/license/codewriter-packages/Tri-Inspector.svg?style=flat-square)](#) [![Unity 2020.3](https://img.shields.io/badge/Unity-2020.3+-2296F3.svg?style=flat-square)](#) ![GitHub package.json version](https://img.shields.io/github/package-json/v/codewriter-packages/Tri-Inspector?style=flat-square)
2022-05-16 02:35:30 -04:00
2022-01-05 08:14:54 -05:00
_Advanced inspector attributes for Unity_
2022-05-14 03:24:26 -04:00
![Tri-Inspector-Demo ](https://user-images.githubusercontent.com/26966368/168415510-819b4fc0-d5ea-4795-b67f-7bd20b2f6adb.png )
2022-05-11 08:13:58 -04:00
- [Attributes ](#Attributes )
2022-05-16 02:35:30 -04:00
- [Misc ](#Misc )
- [Validation ](#Validation )
- [Styling ](#Styling )
- [Collections ](#Collections )
- [Conditionals ](#Conditionals )
- [Buttons ](#Buttons )
- [Debug ](#Debug )
- [Groups ](#Groups )
2022-05-11 08:13:58 -04:00
- [Customization ](#Customization )
2022-05-16 02:35:30 -04:00
- [Custom Drawers ](#Custom-Drawers )
- [Validators ](#Validators )
- [Property Processors ](#Property-Processors )
2022-05-11 08:13:58 -04:00
- [How to Install ](#How-to-Install )
- [License ](#License )
2022-01-05 08:22:07 -05:00
2022-05-11 08:13:58 -04:00
## Attributes
### Misc
2022-05-16 02:35:30 -04:00
2022-05-11 08:13:58 -04:00
#### ShowInInspector
2022-05-11 12:28:37 -04:00
Shows non-serialized property in the inspector.
2022-05-13 03:51:26 -04:00
![ShowInInspector ](https://user-images.githubusercontent.com/26966368/168230693-a1a389a6-1a3b-4b94-b4b5-0764e88591f4.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-13 03:51:26 -04:00
private float _field;
2022-05-11 08:13:58 -04:00
[ShowInInspector]
2022-05-13 03:51:26 -04:00
public float ReadOnlyProperty => _field;
2022-05-11 08:13:58 -04:00
[ShowInInspector]
public float EditableProperty
{
2022-05-13 03:51:26 -04:00
get => _field;
set => _field = value;
2022-05-11 08:13:58 -04:00
}
```
#### PropertyOrder
2022-05-11 12:28:37 -04:00
Changes property order in the inspector.
2022-05-13 03:51:26 -04:00
![PropertyOrder ](https://user-images.githubusercontent.com/26966368/168231223-c6628a8d-0d0a-47c1-8850-dc4e789fa14f.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-13 03:51:26 -04:00
public float first;
[PropertyOrder(0)]
public float second;
2022-05-11 08:13:58 -04:00
```
#### ReadOnly
2022-05-13 03:51:26 -04:00
Makes property non-editable in the inspector.
![ReadOnly ](https://user-images.githubusercontent.com/26966368/168231817-948ef153-eb98-42fb-88ad-3e8d17925b43.png )
2022-05-11 12:28:37 -04:00
2022-05-11 08:13:58 -04:00
```csharp
2022-05-11 12:28:37 -04:00
[ReadOnly]
2022-05-13 03:51:26 -04:00
public Vector3 vec;
2022-05-11 08:13:58 -04:00
```
#### OnValueChanged
2022-05-11 12:28:37 -04:00
Invokes callback on property modification.
2022-05-11 08:13:58 -04:00
```csharp
[OnValueChanged(nameof(OnMaterialChanged))]
public Material mat;
private void OnMaterialChanged()
{
Debug.Log("Material changed!");
}
```
2022-05-11 12:28:37 -04:00
### Validation
2022-05-16 02:35:30 -04:00
Tri Inspector has some builtin validators such as `missing reference` and `type mismatch` error. Additionally you can mark out your code with validation attributes or even write own validators.
2022-05-11 12:28:37 -04:00
2022-05-13 03:51:26 -04:00
![Builtin-Validators ](https://user-images.githubusercontent.com/26966368/168232996-04de69a5-91c2-45d8-89b9-627b498db2ce.png )
2022-05-11 12:28:37 -04:00
#### Required
2022-05-13 03:51:26 -04:00
![Required ](https://user-images.githubusercontent.com/26966368/168233232-596535b4-bab8-462e-b5d8-7a1c090e5143.png )
2022-05-11 12:28:37 -04:00
```csharp
[Required]
public Material mat;
```
2022-05-11 08:13:58 -04:00
#### ValidateInput
2022-05-13 03:51:26 -04:00
![ValidateInput ](https://user-images.githubusercontent.com/26966368/168233592-b4dcd4d4-88ec-4213-a2e5-667719feb0b8.png )
2022-05-11 08:13:58 -04:00
```csharp
[ValidateInput(nameof(ValidateTexture))]
2022-05-13 03:51:26 -04:00
public Texture tex;
2022-05-11 08:13:58 -04:00
private TriValidationResult ValidateTexture()
{
if (tex == null) return TriValidationResult.Error("Tex is null");
2022-05-13 03:51:26 -04:00
if (!tex.isReadable) return TriValidationResult.Warning("Tex must be readable");
2022-05-11 08:13:58 -04:00
return TriValidationResult.Valid;
}
```
### Styling
2022-05-16 02:35:30 -04:00
#### Title
![Title ](https://user-images.githubusercontent.com/26966368/168528842-10ba070e-74ab-4377-8f33-7a55609494f4.png )
```csharp
[Title("My Title")]
public string val;
[Title("$" + nameof(_myTitleField))]
public Rect rect;
[Title("$" + nameof(MyTitleProperty))]
public Vector3 vec;
[Title("Button Title")]
[Button]
public void MyButton()
{
}
private string _myTitleField = "Serialized Title";
private string MyTitleProperty => DateTime.Now.ToLongTimeString();
```
2022-05-11 08:13:58 -04:00
#### HideLabel
2022-05-16 02:35:30 -04:00
![HideLabel ](https://user-images.githubusercontent.com/26966368/168528934-353f2843-b6ea-4f4f-b56e-24e006eca6ae.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
[Title("Wide Vector")]
[HideLabel]
public Vector3 vector;
[Title("Wide String")]
2022-05-11 08:13:58 -04:00
[HideLabel]
2022-05-16 02:35:30 -04:00
public string str;
2022-05-11 08:13:58 -04:00
```
#### LabelText
2022-05-16 02:35:30 -04:00
![LabelText ](https://user-images.githubusercontent.com/26966368/168529002-8fb17112-f74c-4535-b399-aefdb352f73a.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
[LabelText("Custom Label")]
public int val;
[LabelText("$" + nameof(DynamicLabel))]
public Vector3 vec;
public string DynamicLabel => DateTime.Now.ToShortTimeString();
2022-05-11 08:13:58 -04:00
```
#### LabelWidth
2022-05-16 02:35:30 -04:00
![LabelWidth ](https://user-images.githubusercontent.com/26966368/168529051-c90bce09-92a7-4afd-b961-d19f03e826f3.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
public int defaultWidth;
[LabelWidth(40)]
public int thin;
[LabelWidth(300)]
public int customInspectorVeryLongPropertyName;
2022-05-11 08:13:58 -04:00
```
#### GUIColor
2022-05-16 02:35:30 -04:00
![GUIColor ](https://user-images.githubusercontent.com/26966368/168529122-048cd964-358c-453b-ab3a-aa7137bab4f7.png )
2022-01-05 08:14:54 -05:00
```csharp
2022-05-16 02:35:30 -04:00
[GUIColor(0.8f, 1.0f, 0.6f)]
public Vector3 vec;
[GUIColor(0.6f, 0.9f, 1.0f)]
[Button]
public void BlueButton() { }
[GUIColor(1.0f, 0.6f, 0.6f)]
[Button]
public void RedButton() { }
2022-05-11 08:13:58 -04:00
```
2022-01-05 08:14:54 -05:00
2022-05-11 08:13:58 -04:00
#### Indent
2022-05-16 02:35:30 -04:00
![Indent ](https://user-images.githubusercontent.com/26966368/168528565-2972221d-2cb3-49f1-8000-a425e4ff6cea.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
[Title("Custom Indent")]
2022-05-11 08:13:58 -04:00
[Indent]
2022-05-16 02:35:30 -04:00
public int a;
2022-05-11 08:13:58 -04:00
2022-05-16 02:35:30 -04:00
[Indent(2)]
public int b;
2022-05-11 08:13:58 -04:00
2022-05-16 02:35:30 -04:00
[Indent(3)]
public int c;
[Indent(4)]
public int d;
2022-05-11 08:13:58 -04:00
```
#### PropertySpace
2022-05-16 02:35:30 -04:00
![PropertySpace ](https://user-images.githubusercontent.com/26966368/168529641-ee61c950-cb15-4a4e-986b-c9fa8c82dd4d.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
[Space, PropertyOrder(0)]
public Vector3 vecField;
[ShowInInspector, PropertyOrder(1)]
[PropertySpace(SpaceBefore = 10, SpaceAfter = 30)]
public Rect RectProperty { get; set; }
[PropertyOrder(2)]
public bool b;
2022-05-11 08:13:58 -04:00
```
#### PropertyTooltip
2022-05-16 02:35:30 -04:00
![PropertyTooltip ](https://user-images.githubusercontent.com/26966368/168530124-95609470-a495-4eb3-9059-f6203ead995f.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-16 02:35:30 -04:00
[PropertyTooltip("This is tooltip")]
public Rect rect;
[PropertyTooltip("$" + nameof(DynamicTooltip))]
public Vector3 vec;
public string DynamicTooltip => DateTime.Now.ToShortTimeString();
2022-05-11 08:13:58 -04:00
```
#### InlineEditor
2022-05-13 03:51:26 -04:00
![InlineEditor ](https://user-images.githubusercontent.com/26966368/168234617-86a7f500-e635-46f8-90f2-5696e5ae7e63.png )
2022-05-11 08:13:58 -04:00
```csharp
[InlineEditor]
2022-05-11 12:28:37 -04:00
public Material mat;
2022-05-11 08:13:58 -04:00
```
#### InlineProperty
2022-05-13 03:51:26 -04:00
![InlineProperty ](https://user-images.githubusercontent.com/26966368/168234909-1e6bec90-18ed-4d56-91ca-fe09118e1b72.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-11 12:28:37 -04:00
public MinMax rangeFoldout;
[InlineProperty(LabelWidth = 40)]
public MinMax rangeInline;
[Serializable]
public class MinMax
{
public int min;
public int max;
}
2022-05-11 08:13:58 -04:00
```
### Collections
#### ListDrawerSettings
2022-05-13 03:51:26 -04:00
![ListDrawerSettings ](https://user-images.githubusercontent.com/26966368/168235372-1a460037-672c-424f-b2f0-6bf4641c0119.png )
2022-05-11 08:13:58 -04:00
```csharp
[ListDrawerSettings(Draggable = true,
HideAddButton = false,
HideRemoveButton = false,
2022-05-11 12:28:37 -04:00
AlwaysExpanded = false)]
2022-05-13 03:51:26 -04:00
public List< Material > list;
2022-05-11 08:13:58 -04:00
```
### Conditionals
2022-05-11 13:29:20 -04:00
#### ShowIf
2022-05-16 02:35:30 -04:00
![ShowIf ](https://user-images.githubusercontent.com/26966368/168531065-af5dad6a-8aea-4ca9-9730-da5feac0099a.png )
2022-05-11 13:29:20 -04:00
```csharp
2022-05-16 02:35:30 -04:00
public Material material;
public bool toggle;
public SomeEnum someEnum;
2022-05-11 13:29:20 -04:00
2022-05-16 02:35:30 -04:00
[ShowIf(nameof(material), null)]
public Vector3 showWhenMaterialIsNull;
[ShowIf(nameof(toggle))]
public Vector3 showWhenToggleIsTrue;
[ShowIf(nameof(toggle), false)]
public Vector3 showWhenToggleIsFalse;
[ShowIf(nameof(someEnum), SomeEnum.Two)]
public Vector3 showWhenSomeEnumIsTwo;
public enum SomeEnum { One, Two, Three }
2022-05-11 13:29:20 -04:00
```
#### HideIf
2022-05-16 02:35:30 -04:00
2022-05-11 13:29:20 -04:00
```csharp
public bool visible;
[HideIf(nameof(visible))]
public float val;
```
#### EnableIf
2022-05-16 02:35:30 -04:00
2022-05-11 13:29:20 -04:00
```csharp
public bool visible;
[EnableIf(nameof(visible))]
public float val;
```
#### DisableIf
2022-05-16 02:35:30 -04:00
2022-05-11 13:29:20 -04:00
```csharp
public bool visible;
[DisableIf(nameof(visible))]
public float val;
```
2022-05-11 08:13:58 -04:00
#### HideInPlayMode / ShowInPlayMode
2022-05-16 02:35:30 -04:00
2022-05-11 08:13:58 -04:00
```csharp
[HideInPlayMode] [ShowInPlayMode]
```
#### DisableInPlayMode / EnableInPlayMode
2022-05-16 02:35:30 -04:00
2022-05-11 08:13:58 -04:00
```csharp
[DisableInPlayMode] [EnableInPlayMode]
```
#### HideInEditMode / ShowInEditMode
2022-05-16 02:35:30 -04:00
2022-05-11 08:13:58 -04:00
```csharp
[HideInEditMode] [ShowInEditMode]
```
#### DisableInEditMode / EnableInEditMode
2022-05-16 02:35:30 -04:00
2022-05-11 08:13:58 -04:00
```csharp
[DisableInEditMode] [EnableInEditMode]
```
### Buttons
#### Button
2022-05-13 03:51:26 -04:00
![Button ](https://user-images.githubusercontent.com/26966368/168235907-2b5ed6d4-d00b-4cd6-999c-432abd0a2230.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-05-13 03:51:26 -04:00
[Button("Click me!")]
2022-05-11 08:13:58 -04:00
private void DoButton()
2022-01-05 08:14:54 -05:00
{
2022-05-11 08:13:58 -04:00
Debug.Log("Button clicked!");
2022-01-05 08:14:54 -05:00
}
2022-05-11 08:13:58 -04:00
```
### Debug
2022-01-05 08:14:54 -05:00
2022-05-11 08:13:58 -04:00
#### ShowDrawerChain
2022-05-16 02:35:30 -04:00
![ShowDrawerChain ](https://user-images.githubusercontent.com/26966368/168531723-5f2b2d7a-a4c1-4727-8ab5-e7b82a52182e.png )
2022-05-11 08:13:58 -04:00
```csharp
[ShowDrawerChain]
2022-05-16 02:35:30 -04:00
[Indent]
[PropertySpace]
[Title("Custom Title")]
[GUIColor(1.0f, 0.8f, 0.8f)]
public Vector3 vec;
2022-05-11 08:13:58 -04:00
```
### Groups
2022-05-13 03:51:26 -04:00
![Groups ](https://user-images.githubusercontent.com/26966368/168236396-b28eba4a-7fe7-4a5c-b185-55fabf1aabf5.png )
2022-05-11 08:13:58 -04:00
```csharp
2022-01-05 08:14:54 -05:00
[DeclareHorizontalGroup("header")]
[DeclareBoxGroup("header/left", Title = "My Left Box")]
2022-01-30 11:16:17 -05:00
[DeclareVerticalGroup("header/right")]
[DeclareBoxGroup("header/right/top", Title = "My Right Box")]
[DeclareTabGroup("header/right/tabs")]
[DeclareBoxGroup("body")]
2022-01-21 10:15:47 -05:00
public class GroupDemo : MonoBehaviour
2022-01-05 08:14:54 -05:00
{
2022-01-30 11:16:17 -05:00
[Group("header/left")] public bool prop1;
[Group("header/left")] public int prop2;
[Group("header/left")] public string prop3;
[Group("header/left")] public Vector3 prop4;
[Group("header/right/top")] public string rightProp;
2022-01-05 08:14:54 -05:00
2022-01-30 11:16:17 -05:00
[Group("body")] public string body1;
[Group("body")] public string body2;
2022-01-05 08:14:54 -05:00
2022-01-30 11:16:17 -05:00
[Group("header/right/tabs"), Tab("One")] public float tabOne;
[Group("header/right/tabs"), Tab("Two")] public float tabTwo;
[Group("header/right/tabs"), Tab("Three")] public float tabThree;
2022-01-21 06:22:51 -05:00
2022-05-13 03:51:26 -04:00
[Group("header/right"), Button("Click me!")]
2022-01-30 11:16:17 -05:00
public void MyButton()
{
}
2022-01-05 08:14:54 -05:00
}
```
2022-01-15 12:22:33 -05:00
### Customization
#### Custom Drawers
< details >
< summary > Custom Value Drawer< / summary >
2022-01-05 08:22:07 -05:00
```csharp
using TriInspector;
using UnityEditor;
using UnityEngine;
2022-01-06 12:11:27 -05:00
[assembly: RegisterTriValueDrawer(typeof(BoolDrawer), TriDrawerOrder.Fallback)]
2022-01-05 08:22:07 -05:00
public class BoolDrawer : TriValueDrawer< bool >
{
public override float GetHeight(float width, TriValue< bool > propertyValue, TriElement next)
{
return EditorGUIUtility.singleLineHeight;
}
public override void OnGUI(Rect position, TriValue< bool > propertyValue, TriElement next)
{
var value = propertyValue.Value;
EditorGUI.BeginChangeCheck();
value = EditorGUI.Toggle(position, propertyValue.Property.DisplayNameContent, value);
if (EditorGUI.EndChangeCheck())
{
propertyValue.Value = value;
}
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
< details >
< summary > Custom Attribute Drawer< / summary >
2022-01-05 08:22:07 -05:00
```csharp
using TriInspector;
using UnityEditor;
using UnityEngine;
2022-01-06 12:11:27 -05:00
[assembly: RegisterTriAttributeDrawer(typeof(LabelWidthDrawer), TriDrawerOrder.Decorator)]
2022-01-05 08:22:07 -05:00
public class LabelWidthDrawer : TriAttributeDrawer< LabelWidthAttribute >
{
public override void OnGUI(Rect position, TriProperty property, TriElement next)
{
var oldLabelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = Attribute.Width;
next.OnGUI(position);
EditorGUIUtility.labelWidth = oldLabelWidth;
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
< details >
< summary > Custom Group Drawer< / summary >
2022-01-05 08:22:07 -05:00
```csharp
using TriInspector;
using TriInspector.Elements;
[assembly: RegisterTriGroupDrawer(typeof(TriBoxGroupDrawer))]
public class TriBoxGroupDrawer : TriGroupDrawer< DeclareBoxGroupAttribute >
{
public override TriPropertyCollectionBaseElement CreateElement(DeclareBoxGroupAttribute attribute)
{
// ...
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
#### Validators
< details >
< summary > Custom Value Validator< / summary >
2022-01-05 08:22:07 -05:00
2022-01-15 11:25:12 -05:00
```csharp
using TriInspector;
[assembly: RegisterTriValueValidator(typeof(MissingReferenceValidator< >))]
public class MissingReferenceValidator< T > : TriValueValidator< T >
where T : UnityEngine.Object
{
public override TriValidationResult Validate(TriValue< T > propertyValue)
{
// ...
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
< details >
< summary > Custom Attribute Validators< / summary >
2022-01-15 11:25:12 -05:00
```csharp
using TriInspector;
[assembly: RegisterTriAttributeValidator(typeof(RequiredValidator), ApplyOnArrayElement = true)]
public class RequiredValidator : TriAttributeValidator< RequiredAttribute >
{
public override TriValidationResult Validate(TriProperty property)
{
// ...
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
#### Property Processors
< details >
< summary > Custom Property Hide Processor< / summary >
2022-01-15 11:25:12 -05:00
2022-01-05 08:22:07 -05:00
```csharp
using TriInspector;
using UnityEngine;
[assembly: RegisterTriPropertyHideProcessor(typeof(HideInPlayModeProcessor))]
public class HideInPlayModeProcessor : TriPropertyHideProcessor< HideInPlayModeAttribute >
{
public override bool IsHidden(TriProperty property)
{
return Application.isPlaying;
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
< details >
< summary > Custom Property Disable Processor< / summary >
2022-01-05 08:22:07 -05:00
```csharp
using TriInspector;
using UnityEngine;
[assembly: RegisterTriPropertyDisableProcessor(typeof(DisableInPlayModeProcessor))]
public class DisableInPlayModeProcessor : TriPropertyDisableProcessor< DisableInPlayModeAttribute >
{
public override bool IsDisabled(TriProperty property)
{
return Application.isPlaying;
}
}
```
2022-05-16 02:35:30 -04:00
2022-01-15 12:22:33 -05:00
< / details >
2022-01-05 08:22:07 -05:00
2022-01-05 08:14:54 -05:00
## How to Install
2022-05-16 02:35:30 -04:00
2022-01-21 23:36:15 -05:00
Minimal Unity Version is 2020.3.
2022-01-05 08:14:54 -05:00
Library distributed as git package ([How to install package from git URL](https://docs.unity3d.com/Manual/upm-ui-giturl.html))
< br > Git URL: `https://github.com/codewriter-packages/Tri-Inspector.git`
2022-05-16 02:35:30 -04:00
After installing the package, you need to unpack the `Installer.unitypackage` that comes with the package.
2022-05-13 03:51:26 -04:00
Then in `ProjectSettings` /`TriInspector` enable `Full` mode for Tri Inspector.
2022-05-08 07:21:18 -04:00
2022-01-05 08:14:54 -05:00
## License
Tri-Inspector is [MIT licensed ](./LICENSE.md ).