Advanced Inspector - Never Write An Editor Again

Available on the Asset Store.

Advanced Inspector - Manual
Advanced Inspector - Tutorials

FOR DIRECT SUPPORT, JOIN OUR DISCORD CHANNEL

The Inspector, or in other engine the “property grid”, is one of the most important tool we have to use. It’s the window to all our data, and if this tool is lacking, everything we do and how fast we do it, will also suffer from it.

There’s lot of Inspector package in the Asset Store, but none that we feel give us the “full package”. To solve this issue, we’ve been working on this package for over seven months. One of the first thing we found out is, the classes behind the Inspector - SerializedProperty, SerializedObject - were also too limited for our needs, surprisingly restrained to a single serialization context. We rewrote them from scratch.

In this package, everything how the Inspector draw and handle data have been reworked from the ground up. “Advanced Inspector” is what we believe Unity’s Inspector should have been from the start. Please consult the manual for an up-to-date list of the features.

https://www.youtube.com/watch?v=OUFMgCBoCao

Basic Features

That being said, we had to support at least as much as what Unity does;

  • Undo
  • Prefab handling
  • Multi-object editing
  • “Script” field

Here’s a list of the basic features that Unity’s Inspector does not support and we added;

  • Every non-static fields, properties or parameter-less method can be exposed.

  • Every list and array now have +/- button to add and remove index.

  • Every list and array’s nodes can be dragged around to reorder them.

  • Every field can be expanded to display the inner fields, being in a list or not.

  • Every type’s editing field is now handled by a “field editor”.

  • Every label can be right-clicked for a contextual menu. Extra “type-dependent” menu can be added from its field editor.

  • Every fields can be copy/pasted, even complex type, such as struct, or ComponentMonoBehaviour hierarchy.

  • Every fields can be apply or reverted independently. No need to apply/revert the whole prefab.

  • Every fields can have a URL to an help page.

  • Every fields is fully dynamic; can be hidden, renamed, change color, display help box or change how the data is exposed at runtime.

  • Unlimited number of depth, not limited to a single serialization context.

  • The inspector is now separated into two columns, one for the labels, one for the editing field. The separator can be moved around, no space wasted.

  • Support for Unity’s “exotic” type, such as LayerMask, Color32 or Bounds.

  • Add new data type, like Unity-friendly Dictionary, Ranges or Action Bindings

  • Control the Preview section of the Inspector without a custom editor.

  • and much more.

Sub Components

Another important feature that we used to have in other engines was the ability to create polymorphic sub-component directly from the property grid. The same way components in a GameObject are useful, breaking down a complex behaviour into smaller parts is also incredibly important. This design is usually named “Composition”. However, Unity doesn’t support serialization of polymorphic object deriving from System.Object.

To solve this issue, the new Inspector handles a new base class - ComponentMonoBehaviour - differently.

When a field is flagged with “CreateDerived” attribute, the normal object field is turned into the above. The “+” sign, when clicked on, display the list of class that derive from this base type. Selecting one create an instance of that type. When a field is filled, the “+” sign turns into a “-” sign to destroy that instance.

There’s an unlimited number of depth in “sub-components” references. It is, we believe, one of the most powerful feature of this package, as we use it on a daily basis.

Attributes

To handle how all the data is handled and drawn, there’s now a huge list of attributes that can be placed on classes, fields, properties or even methods. Each modify the final result, and in most case, that can be combined with each other for very specific behaviour.

  • AdvancedInspector: Allow to hide the script or prevent the default Unity’s behaviour of inspecting serialized item.

  • Angle: Turn a int or float field into a spinning angle wheel that can be set to increment over specific values.

  • Bypass: When a Field/Property of a Unity type is flag with it, its internal values are displayed using the Advanced Inspector.

  • CollectionConstructor: Allows item created in a list/arrow to be created from a method of your choice. It is now possible to populate a list from object with a specific constructor!

  • CreateDerived: Allow the user to create an instance deriving from this field/property base type.

  • Descriptor: Change the Field/Property name, tooltip, or even color. This is a runtime attribute.

  • DisplayAsParent: A nested object is displayed as being part of the parent.

  • DontAllowSceneObject: Object picker ignores the current scene and only list the project’s objects.

  • Expandable: Override the expandability of an item.

  • FieldAttribute: Similar to Unity’s property drawers, but can be applied to non-serialized fields, properties and method. Also support Layouting.

  • FieldEditor: Override a specific field/property to use an alternative field editor.

  • Group: Group a collection of field under the same drop down.

  • Help: Display a help box under this field. This is a runtime attribute.

  • Inspect: Flag the member you wish to display on the inspector. It is not related if this value is serialized of not. This is a runtime attribute.

  • MaskedEnum: Turn an enum into a masked enum. (bitfield)

  • RangeValue: Same as Unity’s Range attribute, but not restricted to Field placement.

  • ReadOnly: Prevent this field from being edited, but is still displayed. This is a runtime attribute.

  • Restrict: Turns any field into a drop down list of specific choices. This is a runtime attribute.

  • RuntimeResolve: The FieldEditor is fetch using the runtime type instead of the field type, or you can force a specific type to be used - useful when the value is null.

  • Size: Force a list or array to be of a fixed size.

  • Space: Add space after this field.

  • Style: Force a field to be drawn using an alternative GUIStyle.

  • Tab; Classify your fields under tabs.

  • TextField: Change a string field into; Text Field, Text Area, Password, Tag, File Picker, Folder Picker

  • Toolbar: Group item horizontally in a toolbar.

Most attributes have plenty of parameters to make them as flexible as possible. Listing every possibility would be far too long.

Runtime attribute are able to take a method’s name or a delegate to retrieve their current settings at runtime. Which mean, you can bind a field to another, change a help box message, or even change the name and color of a field based on whatever condition you want. The system also pass down any attribute sporting IListAttribute interface to the children field of a list or array.

The system is also fully extensible to support your own type or your own attributes. There is no limit to the number of attribute a member can sport. You can still write your own Editor while using the feature of the Advanced Inspector. We rewrote Unity’s type editor this way. You can also write your own FieldEditor if you want to display a specific type in a specific way.

Type-bound PropertyDrawer are supported since version 1.52.
Attribute-bound PropertyDrawer are supported since version 1.67.
FieldAttribute and FieldEditor replaces PropertyDrawers, without the limitation!

Current version on the Asset Store; 1.72a (Supports Unity 5.2, 5.3, 5.4, 5.5, 5.6 and 2017.1)
Current issue exists on .NET 4.6.
See the manual for the latest changelist.

Note that version 1.60+ is only supported on Unity 5.2 and above.
Version under 1.60 is supported on 4.3, 4.6, 4.7 and 5.0.

4 Likes

I would like to know what people think would be a good price, what features they feel are missing or think would be interesting to add in this context.

This is a pretty neat inspector indeed. It adds a lot of features that Unity lacks.

As for the price, Jacob Dufault’s Full Inspector is currently priced at 25$. Both inspectors seem relatively different, but I wouldn’t overprice it either. I’d say that 25-50$ would be a reasonable price, I guess.

As for the features, does it supports Dictionaries and Scriptable Object?

I feel like going higher than that would turn people away from it. Even though I’d be ready to pay more for a more decent inspector

Leaning towards ~35$ right now… I have a feeling I’ll need to give lot of support. Will probably setup a forum somewhere for questions and features request. Building the documentation right now, and I’m easily going over 30 pages for just listing the features and what they do. I’ll probably release that documentation soon so people understand exactly what this package does.

Right now, it’s not modifying Unity’s serialization, which means dictionary are not serializable. There’s easy ways to counter that, like breaking the dictionary into two list at serialization and rebuilding it at deserialization. However, displaying dictionary could still be useful. I’m adding that to my list of todo.

As for ScriptableObject, I’m not sure what you mean. It works perfectly on ScriptableObject right now, but maybe you had something specific in mind?

The ScriptableObject part was me thinking you overhauled Unity’s serialization process. Did you manage to find a workaround to expose abstract classes/interfaces implementations in the editor?

Keep me informed on when it’ll come out. It seems like a very good add-on

Abstract class - when deriving from the proper Unity’s serialization entry point; MonoBehaviour and ScriptableObject, always worked fine… But have been a major pain to properly integrate and handle in the Inspector as there was no way to choose a derived type to instantiate. “CreateDerived” attribute is the solution that have been implemented to make it easy as pie to handle for the designer and the coder.

Here’s a screenshot of a camera system built using composition of abstract classes;

Every exposed parts of the system are base abstract classes. It works like a lego blocks system, where the designer adds the parts he needs and plugs them one into the others. There’s an unlimited depth of nesting when it comes to those abstract type. The copy/paste system also handles those “components” as being object and not reference. So copying the root duplicates the whole hierarchy properly.

As for interfaces, the issue is the same as normal Unity’s serialization… It’s not supported. The only way to have interface serialized is to go the Full Inspector way’s and use an alternate serialization pipeline. However, in all the games I have made, replacing an interface for an abstract base class worked all the time. Usually the design rework to pass from an interface to an abstract is minimal. I’m not saying it always worked, simply that I haven’t encountered a case where it didn’t yet.

I’ll have the documentation online this week, so it will become much clearer.

Do you have an ETA on the asset store release?

Unity takes 3 to 5 days of approbation on asset. From what I understand, it also depends on the asset complexity… So I guess this one will go more towards the 5 days or more.

My plan is to finish the documentation today, takes the rest of the week reviewing, packaging and testing, and hopefully submit it by next Monday. I have a few minor fix to do such as converting an array implementation into IList instead. Minor stuff.

I hope to not get my package refused because of http://forum.unity3d.com/threads/231232-Asset-Store-Limitation , considering the amount of work put into it.

Advanced Inspector is now available on the Asset Store.

Wow that video made this quite clear…very awesome. Also made it clear to me that I need to get up to speed with C#! (I’m assuming this doesn’t work with JS?)

Good stuff man!

-Steven

It is possible to mix different language… Even if I never tried it myself. From what I read, you have to place your script - that would derive from the packaged one - in a folder that would be compiled after; http://docs.unity3d.com/Documentation/Manual/ScriptCompileOrderFolders.html

In this case, you could move the DLL into the /Plugins/Editor folder and place your own JS script in /Editor.

Version 1.1 will soon be submitted to the Asset Store.

As seen here;

Unity is rolling out in 4.6 “Action” field as a way to bind an event to a method. We heard lot of people being excited by the features… We wondered if we could do the same, with maybe more option and features, without having to code a custom editor.

So… we did.

Those “ActionBinding” can be placed in a collection too;

[AdvancedInspector]
public class AIExample_Binding : MonoBehaviour
{
    [Inspect]
    public ActionBinding onClick = new ActionBinding(new Type[] { typeof(Material) } );

    [Inspect]
    [CollectionConstructor("OnReleaseConstructor")]
    public ActionBinding[] onRelease = new ActionBinding[0];

    private object OnReleaseConstructor()
    {
        return new ActionBinding(new Type[] { typeof(Material) });
    }

    private void OnMouseDown()
    {
        onClick.Invoke();
    }

    private void OnMouseUp()
    {
        foreach (ActionBinding action in onRelease)
            action.Invoke();
    }
}

They can have an unlimited number of parameters. They support all the types Unity serializes.
Each parameter can work in 3 modes;

  • Internal; the argument is passed by the class invoking the action in the Invoke method.
  • Static; the argument is manually set in the inspector.
  • External; the argument is retrieved from an other method invoked. Only parameterless methods with the proper return type are listed.

And other fixes and modifications coming with 1.1;

  • Fixed the Camera preview
  • Fixed the Camera perspective/orthographic drop down with new RestrictedAttribute option.
  • Added a way to decouple data from description in the RestrictedAttribute. Just pass DescriptorPair instead of the object directly.
  • Added a missing constructor in ReadOnlyAttribute.
  • Changed the constraint field in the RigidBody because “I prefer the checkboxes”.
  • Non-editable expandable field - such as object deriving from System.Object - now display info in the format “ToString() [Class Name]”. Overriding ToString becomes useful.
  • Fixed a null in the Restricted > Toolbox.
  • SizeAttribute can now flag a collection as not-sortable.
  • Added a new Attribute; RuntimeResolve which display a field editor based on the object’s type or a type returned by a delegate, instead of the field type. It can also be used to restrict a Object field to a specific type. For example, you can make a UnityEngine.Object field only display Material.
  • Added a new Attribute; CollectionConstructor which let you create a collection item with the constructor and parameter of your choice.

You’re correct about the script relocation, yes.

Now just to be certain, could you demonstrate the use of JS with Advanced Inspector? You could even take one of your original videos and just duplicate the demo, and code using javascript.

This isn’t to waste your time mind you, but only to ensure that this is as feature rich and robust with JS. I would love to have the time currently to get as proficient with C# as I am with JS, and believe you me I understand the value, but knowing I can fall back to JS would give me great confidence.

Thanks!

-Steven

Well, I don’t think I will redo that video for JS.

However, in the package, there’s a lot of implementation examples, some shown on the demo video. I’m currently rewriting them all into JS, so the version 1.1 will have examples both in C# and in JS.

In part of that, the 1.1 will have its whole structure moved to Plugins and Plugins/Editor, which makes more sense too. So people who want to use other language won’t have any manipulation to perform.

Here’s the example about sorting redone in JS;

#pragma strict

// The Advanced Inspector has three sorting option in the contextual menu.
// Alphabethic, Anti alphabetic, and none.
// No matter the sorting chosen, the Priority of an item has priority over the sorting.
// When using "none" as sorting, the items are listed as they are found in the code.
// By default, the AI get the method first, properties second and field last.
// In this example, since every item has specific Priorities, the order stay fixed no matter the sorting chosen.
@AdvancedInspector
public class AIExampleJS_Sorting extends MonoBehaviour
{
	@Inspect(2)
	function Method() { }

	var myFloat : float;
	 
	@Inspect(1)
	public function get MyFloat() : float
    {
        return myFloat;
    }
    
    public function set MyFloat(value : float)
    {
        myFloat = value;
    } 

	// The default value of Priority is 0.
	@Inspect 
	function OtherMethod() { }

	// Negative value works just fine.
	@Inspect(-1)
	var myInteger : int;  
}

Little things about JS…

  • You only need to flag @Inspect on one accessor of a property.
  • JS doesn’t have the notion of abstract classes, so the CreateDerived flag also list the base class as a valid choice. This could be an issue if you don’t want someone to create an instance of a base class.

Oh, well there you go! You just got yourself another sale!!

(We need more people talking about this…rarely am I this impressed with Editor/Inspector based assets…) :smile:

Bravo man thank you!!

-Steven

1.1 should be submited for review for the Asset Store tomorrow.

Meanwhile, here’s a gif that show how Copy/Paste is not limited to simple type like float, but support complex nested structure, reference, and so on… You can even paste a full collection, or paste on a collection index;

Version 1.1 was submitted to the AssetStore.
(And 1.1a was submitted 20 mins later because we rebuilt the Library, nuking all our script reference in our examples)

Changelist;

  • Fixed the Camera preview (the window can be dragged around properly)
  • Fixed the Camera perspective/orthographic drop down with new RestrictedAttribute option.
  • Added SkinnedMeshRenderer and Text Mesh as converted editor.
  • Added a way to decouple data from description in the RestrictedAttribute. Just pass DescriptorPair instead of the object directly.
  • Added a missing constructor in ReadOnlyAttribute.
  • Changed the constraint field in the RigidBody because “I prefer the checkboxes”.
  • Non-editable expandable field - such as object deriving from System.Object - now display info in the format “ToString() [Class Name]”. Overriding ToString becomes useful.
  • Fixed a null error in the Restricted > Toolbox.
  • SizeAttribute can now flag a collection as not-sortable. Useful for collection which the order comes from the code and should not be changed.
  • Added a new Attribute; RuntimeResolve which display a field editor based on the object’s type or a type returned by a delegate, instead of the field type.
  • It can also be used to restrict a Object field to a specific type. For example, you can make a UnityEngine.Object field only display Material.
  • Added a new Attribute; CollectionConstructor which let you create a collection item with the constructor and parameter of your choice.
  • Moved the asset into Plugins and Plugins/Editor folder, so other language - like JS - can be supported without modification.
  • Copied the Examples asset into JavaScript, also used to test other language support.
  • Added a class named “ActionBinding” which is a way to bind an event to a data-driven method invokation. Similar to what Unity will roll out in 4.6 with their new GUI… but better.
  • Take a look at the video for more information. It’s an example of what the AI can do, as no editor were writing for that class.

[SOLVED] This was a problem with Unity Serializer 2.0.

I get this error on import:

The solution seems to be here:

Right now, the 1.0 version on the Asset Store is colliding with Unity Serializer. Thanks to Stardog for spotting it. However, there is no class name colliding. We are still a bit puzzled as to why it doesn’t like both package at once. We noticed that taking an Editor folder outside the Plugins folder solves the issue, which is rather odd.

Version 1.1 - which is currently in validation by Unity - is not colliding with this package. It should be available on the store this week.

this tool has lots of functionality that I felt is needed in the editor. it’s a buy from me.
nice job on the asset!