Search Unity

Advanced Inspector - Never Write An Editor Again

Discussion in 'Assets and Asset Store' started by LightStriker, May 4, 2014.

  1. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717

    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.










    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.
     
    Last edited: Nov 10, 2017
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
  3. Clet_

    Clet_

    Joined:
    Oct 31, 2013
    Posts:
    7
    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
     
    Last edited: May 6, 2014
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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?
     
    Last edited: May 12, 2014
  5. Clet_

    Clet_

    Joined:
    Oct 31, 2013
    Posts:
    7
    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
     
    Last edited: May 13, 2014
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
  7. Clet_

    Clet_

    Joined:
    Oct 31, 2013
    Posts:
    7
    Do you have an ETA on the asset store release?
     
  8. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
  9. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Advanced Inspector is now available on the Asset Store.
     
  10. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Posts:
    1,451
    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
     
  11. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
    Last edited: May 24, 2014
  12. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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;


    Code (csharp):
    1.  
    2. [AdvancedInspector]
    3. public class AIExample_Binding : MonoBehaviour
    4. {
    5.     [Inspect]
    6.     public ActionBinding onClick = new ActionBinding(new Type[] { typeof(Material) } );
    7.  
    8.     [Inspect]
    9.     [CollectionConstructor("OnReleaseConstructor")]
    10.     public ActionBinding[] onRelease = new ActionBinding[0];
    11.  
    12.     private object OnReleaseConstructor()
    13.     {
    14.         return new ActionBinding(new Type[] { typeof(Material) });
    15.     }
    16.  
    17.     private void OnMouseDown()
    18.     {
    19.         onClick.Invoke();
    20.     }
    21.  
    22.     private void OnMouseUp()
    23.     {
    24.         foreach (ActionBinding action in onRelease)
    25.             action.Invoke();
    26.     }
    27. }
    28.  
    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.
     
    Last edited: Jul 19, 2014
  13. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Posts:
    1,451
    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
     
  14. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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;

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. // The Advanced Inspector has three sorting option in the contextual menu.
    5. // Alphabethic, Anti alphabetic, and none.
    6. // No matter the sorting chosen, the Priority of an item has priority over the sorting.
    7. // When using "none" as sorting, the items are listed as they are found in the code.
    8. // By default, the AI get the method first, properties second and field last.
    9. // In this example, since every item has specific Priorities, the order stay fixed no matter the sorting chosen.
    10. @AdvancedInspector
    11. public class AIExampleJS_Sorting extends MonoBehaviour
    12. {
    13.     @Inspect(2)
    14.     function Method() { }
    15.  
    16.     var myFloat : float;
    17.      
    18.     @Inspect(1)
    19.     public function get MyFloat() : float
    20.     {
    21.         return myFloat;
    22.     }
    23.    
    24.     public function set MyFloat(value : float)
    25.     {
    26.         myFloat = value;
    27.     }
    28.  
    29.     // The default value of Priority is 0.
    30.     @Inspect
    31.     function OtherMethod() { }
    32.  
    33.     // Negative value works just fine.
    34.     @Inspect(-1)
    35.     var myInteger : int;  
    36. }
    37.  
    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.
     
  15. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Posts:
    1,451
    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...) :D

    Bravo man thank you!!

    -Steven
     
  16. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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;

     
  17. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
    Last edited: Jul 19, 2014
  18. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,912
    [SOLVED] This was a problem with Unity Serializer 2.0.

    I get this error on import:

    The solution seems to be here:
    http://forum.unity3d.com/threads/internal-compiler-error.110424/
    http://answers.unity3d.com/questions/636739/reflectiontypeloadexception.html
    http://answers.unity3d.com/questions/614268/added-custom-dll-internal-compiler-error.html
     
    Last edited: Jun 3, 2014
  19. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    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.
     
  20. mboog12

    mboog12

    Joined:
    Oct 4, 2011
    Posts:
    91
    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!
     
  21. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Version 1.1a is now available on the Asset Store.
     
  22. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Version 1.2 Changelist:
    • Fixed an issue with Editor object showing the log message about no reference towards them when saving a scene. It was harmless, but annoying.
    • Fixed an issue with internal texture showing the same log message.
    • Fixed a index exception while deleting an item in some specific cases. It was harmless, but annoying.
    • Fixed the multi-edition on boolean editor.
    • Update some internal icon; +, -, open, closed and the drag icon. They should be easier to see in both light and dark.
    • Added IPreview interface that gives control over the preview panel of the inspector. New class in the DLL; InspectorPreview.
    • Added a new attribute; "Tab". Draws toolbar-like tabs at the top of a script, similar to the SkinnedCloth component.
    • Added the standard "on scene" collider editor on the Box, Capsule, and Sphere collider.
    • Added a class named TypeUtility. It is used only to retrieve a type in all loaded assembly based on its name.
    • Added SkinnedMeshRenderer, TextMesh and Mesh editor.
    • Added "very large array" support. Any collection having over 50 items only displays 50, and have arrows at the top and bottom to navigate in them.
    • Added UDictionary, a fully Unity-serializable dictionary for Unity 4.5 and later. Does not work on previous Unity version.
    • Added RangeInt/RangeFloat, struct used to set a minimum and a maximum. They use Unity's MinMaxSlider.
    • The Space attribute can now add space before an item and/or after it. Before default size is 0, after default size is 1. Does not change existing behaviour.

    Will soon be submitted to the AssetStore once the documentation is updated.

    Tabs;


    RangeInt / RangeFloat;


    Dictionary (Unity 4.5 only);


    Preview;


    Very Large Collection;


    For more information, see the WIP Thread; http://forum.unity3d.com/threads/advanced-inspector-wip-feature-requests.248039/
     
    Last edited: Jul 19, 2014
  23. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
  24. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    Congrats on the release! Just playing around with it now… Is it possible to rename or remove the labels on a list?



    For example, I'd like where it says "TutorialStoryData+Story [Story]" to use the property of "Name". And hide the label that says "TutorialStoryData+DateClass [DateClass]"
     
  25. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It's actually very easy Essential, you simply need to overwrite the "ToString" method in your class. Every object in C# automatically implement this method. However, if you do no override it, it just output the class' name.

    Code (csharp):
    1. public override string ToString()
    2. {
    3.     return name;
    4. }
    or if you want nothing to show up;

    Code (csharp):
    1. public override string ToString()
    2. {
    3.     return "";
    4. }
    Don't hesitate if you have any more issues, feedbacks, ideas, bugs or feature requests. We'll try to answer them as quickly as possible.
     
    Last edited: Jul 4, 2014
  26. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    Thanks LightStriker, I was able to change the title but unfortunately I can't seem to get rid of the ClassName in square brackets on the end. How can I get rid of that?
     
    Last edited: Jul 5, 2014
  27. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Sorry, not right now. However, in the next version (1.3), it shows that "[class name]" part only if the class is not the same as the collection base type.

    If you do a List<Story> and they are all "Story", it's redundant to tell you it's a story.

    How it's going to look like in 1.3;

     
    Last edited: Jul 5, 2014
  28. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    Cool, I'm looking forward to future updates. I feel like telling extra info like this though (the variable type, class type, etc.) might be better to be an optional extra that advanced users can turn on if they want to show it. Is it necessary when entering data to know that the variable Nested List is an Array of NestedList? I personally want to try and hide that stuff to keep it as clean and simple as possible.

    Generally it's a good tool though, it's saving me a lot of time. I have a bit more feedback, mostly relating to the display of lists, but I’ve included some general usage feedback too:
    • I think all values that can be inspected in the Unity Inspector should be set to Inspectable by default. I think it’s much more user friendly for someone to just add the [AdvancedInspector] tag to a script and have it automatically show in the inspector and then make adjustments based off that, rather than the current setup. I found myself having to go through a script adding the [Inspect] tag to many variables.
    • The list remove item buttons ( – ) are right in between the foldout arrow and the draggable control… I think this will result in accidental deletions. I think the remove button should be pushed over all the way to the far right edge of the screen.
    • I feel a slightly more user-friendly arrangement of controls is: draggable control first, foldout arrow second.
    • Is it possible for the remove item button to have a confirmation popup before deleting an item?
    • Foldout arrows, + icons, and - icons all have shadows but I think they’d look better being consistent with normal Unity GUI (no drop shadows).
    • As addressed in my earlier comment regarding changing the titles of elements, I’m not sure if it's necessary to display object names by default — perhaps this should be an advanced option? The titles could also be formatted a bit cleaner… E.g., “List of Story (10)” looks a little better than “List of Story[10]”.
    • When hovering cursor over a draggable control, perhaps it could change to a different icon (hand?) to indicate that it is draggable.
     
  29. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Good point, since on a Dictionary, there isn't even space for that info. I'll make that the next version only display the collection type in advanced or debug mode.

    Frankly, this is probably the thing that had generated the most back and forth at the beginning of this tool. The problem is the AI is completely uncoupled from the serialization, and we know by default the normal Inspector is only displaying serialized item. Which mean it can display everything Unity is usually unable to display. It's most likely something we could tweak, but I feel we would have to be extra careful.

    Reading what you just said gave me an idea... It could simply be a switch in the AdvancedInspector attribute, like "InspectDefaultItems" and it would parse the fields like Unity does. Adding [Inspect] only to the items Unity usually doesn't display would add them to the list.

    Far edge of the screen? Probably not. However, I do understand your concern and I have deleted a few items by accident myself. Good thing the undo usually works fine. However, moving the delete button... somewhere else, is really something I'll look more into.

    The problem I see with this is that for some item the foldout arrow come first, and for other it would not be first. Frankly, I prefer if the foldout arrow is at the same place for all item. However, if I move the delete control somewhere else, it will make the drag control right next to the foldout arrow.

    I really don't think this should be a default behaviour. If I have to delete many items, it would piss myself off to have to confirm it all the time. However, that could definitely be an option added per field or per object.

    Point taken. The shadows were an experiment in the last version to see if I could make the control popup out more. I'll revert those changes.

    See my first comment... That title will now only show up in Advanced or Debug mode. As for [] vs ()... I truly have no idea. Usually, brackets are related to collection, no?

    Very good point. Adding that.
     
    Last edited: Jul 5, 2014
    IvanAuda likes this.
  30. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    @LightStriker Good points, and good idea with parsing the fields the same as Unity, I think that's the most expected behavior. Then a user can tag items to customize further, or to hide, etc.

    As for the delete item button, I was reminded today that Unity's native Script Execution Order function arranges the controls like below, so perhaps you could do something similar.



    I'll look forward to future releases and keep an eye out for new features I can suggest.
     
  31. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Thanks to ton of feedback, the next version has the longest changelist and the biggest changes so far.

    Changelist for the upcoming version 1.3;

    • IMPORTANT: All classes related to the Advanced Inspector have been moved to the AdvancedInspector namespace, for consistency with other assemblies (Ex.: System.Serializable) and not to pollute the global scope.
    • The AdvancedInspector Attribute now have "InspectDefaultItem" property, which emulate the way Unity display items without the need to add [Inspect] on all your items. You can still inspect item Unity would not display by adding the Inspect Attribute.
    • Help Attribute can now be tagged on a class, giving a help box in the header or footer. You can also place multiple instance of the Help attributes, which displays multiple help box.
    • Help Attribute now has the "Position" property, which place the help box before or after the targeted member, or in case of a class, in the header or footer.
    • Expandable Attribute now has the "Expanded" property, which forces an item to be expanded by default when first viewed.
    • Group Attribute now has the "Expandable" property, which when false, the group is not collapsable and remains open, serving has a dividing box.
    • Added a layout "header" and "footer" at the top and bottom of the inspector, before and after all the fields.
    • Added an interface; IInspectorRunning, which gives access to the Header and Footer zone in the form of a OnHeaderGUI and OnFooterGUI method.
    • InspectorField now support SerializableProperties, but please do not use it, it's most likely full of bug since SerializedProperty is anything but generic.
    • CTRL + Click expand all the child of the item expanded. (Ex.: All the subobject in a list)
    • Removed the "[class name]" part of the label of a list when that item is the same type as the list itself. (Ex.: List<item>, no need to tell you it's an item)
    • The collection type is now only display in Advanced or Debug mode.
    • Removed the "shadows" from the following icon; add, delete, folder open, folder close.
    • Fixed a null exception thrown when using enums in a Dictionary.
    • Added cubemap to the supported type in the Preview.
    • Reworked the layout a lot, such as adding 4 pixel to the left of the fields so they don't stick to the window. Now nested item are "boxed-in", which should make multi-level items easier to read.
    • Lined up lot of items and subitem that were not properly lined up in specific case in both their label and fields.
    • Fixed the Example6 where nested class where not serialized.
    • Added methods "GetAttributes" and "GetAttributes<T>" to the Inspector field, returning all instance of a multi-attributes.
    • Fixed the aspect ratio in the Camera preview on Scene.
    • SkinnedMeshRender "Bones" property is no longer "read only", but it is now an advanced property.
    • Added LightEditor to support Unity's Lights.
    • Added support for the Gradient type, another of those fancy hidden thing in Unity.
    • The cursor is now a "grab hand" when hovering over the drag control.
    • Added an EditorWindow example of external inspector.
     
    Last edited: Jul 19, 2014
    IvanAuda likes this.
  32. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
  33. Shinzironine

    Shinzironine

    Joined:
    Nov 30, 2013
    Posts:
    32
    Advanced Inspector looks great. I'm most of all interested in the SubComponents feature. I am now reading the documentation and you refer to the ComponentMonoBehaviour chapter in the section CreateDerived (page 22), but there is no such chapter. Have I overlooked one or is there a separate doc?
     
  34. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Oh... Ouch. Well, that's what happen when nobody review the documentation. I'll update it, sorry.

    As for now, I can always explain what's the purpose of this abstract class.
    Unity's issue is the lack of polymorphic support except in 2 specific cases; ScriptableObject and MonoBehaviour. Everything else loses its types and revert to the field's type on serialization.
    So a sub-component must derive from one of those two to retain its proper polymorphic property as serialization. Sadly, ScriptableObject are not save-able in prefabs, so that rules them out.

    To make a MonoBehaviour to act as a sub-component of another, the AdvancedInspector perform quite a few tasks in background. The ComponentMonoBehaviour stores its parent at creation, so if the parent is destroyed, the sub-component is also automatically destroyed. The AdvancedInspector performs checks on any selected GameObject and destroy any orphan ComponentMonoBehaviour, so that no left over is wasting memory or performance.

    Note that there is unlimited number of level of nested sub-component; sub-component can have their own sub-component too. The AdvancedInspector also makes sure the sub-component are not handled as standard MonoBehaviour, so they are not displayed independently in the inspector, but only as being part of their parent.

    Finally, the AdvancedInspector handles sub-component differently when it comes to copy/pasting them. When you copy/paste an object deriving from UnityEngine.Object, only the reference is copied over. Everything else is deep-copied recursively. However, sub-component are handle as if they were not deriving from UnityEngine.Object, and are deep-copied, to keep the rule that a sub-component can only exist at one place and have one parent.

    Here's a camera system that have been built using this method, it's a good example of a composition pattern;


    The camera behaviour have been split into all its logical parts. So now the designer can assemble the camera he wants using all those separated blocks. In other words, this camera system can do EVERY camera you or the designer can imagine, and can transition from one context to another all by itself.

    There's a few very useful advantage;
    - Very easy and fast to create or destroy sub-components, can be handled like lego blocks.
    - Adding new sub-component type is as easy as writing the class, everything else is done by reflection.
    - Unlike most AssetStore system, no extra GameObject are created per items, and the Inspector is not clogged with extra MonoBehaviour, the sub-component is only visible in its parent.
    - Can be put in prefab, copied, and the system keeps its structure and integrity.
    - Very hard to properly do composition pattern or your own component pattern without it.

    Here's example of a component-pattern system that was built around the ComponentMonoBehaviour;


    Each "clip" in this logic flow chart is a ComponentMonoBehaviour added to the GameObject containing that chart. The parent of the clips is the chart itself. So if I delete the chart, all the clip are deleted too. In this case, the clips are not added in the Inspector itself, but in this custom EditorWindow.

    The number of application is endless. Imagine you have a AI and you want to choose which attack pattern it should perform. The attack pattern can be a sub-component.

    It's a system I used on a daily basis, and my life would be quite more painful without it. :D
     
    Last edited: Jul 11, 2014
  35. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    Hey @LightStriker — Just got the new version and it looks GREAT! Lots of nice little aesthetic changes to the way lists are displayed, and the little hand cursor just *feels* real nice now. :) But I noticed your technique to override the ToString method with my item names is no longer working… is that not possible to use with the new version?

    I also have a small question regarding expanding. I don't think Advanced Inspector currently saves editor prefs (e.g., which list items are expanded or not), and currently my lists all collapse after running the game. I'm hoping you can automatically save these properties in a future release, but in the mean time how can make all items in a list to be forced expanded? The manual says I need to set 'Expanded' to equal true, but I'm not sure how exactly to do this?
     
  36. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It still works... Only not in all cases. You see, right now I haven't put in places check to see if your class really override ToString or it doesn't, and I'm not even sure if it's possible. When it is not overriden, the method ToString returns the class name, and I got people telling me they didn't like that showing up, which is horribly ugly in case of nested class. So right now, the ToString is only displayed if the field type is not equal to the object type. So... if you are not using CreateDerive and ComponentMonoBehaviour, right now, it's probably not showing anything.

    I plan on doing a quick 1.31 version soon to add some quick fix. I need to find a way to sort it if ToString is properly overriden or not... Or make another method on my own. Still not sure, but quite open to ideas on this.

    It's true, currently nothing is saved and everything is flushed between reload. It's a good idea to try to save stats in EditorPrefs, I'll look into it. Save thing with the Basic/Advanced/Debug mode that should probably be saved too.

    As for using "Expanded" property, let's say you have the class;

    Code (csharp):
    1. [Expandable] // Usually you use that attribute to make it expandable
    2. public class MyItem { }
    And you want it to always show up as being expanded, you do;

    Code (csharp):
    1. [Expandable(true)] // Forces the default state to expanded
    2. public class MyItem { }
    In the examples, the class AIExample_ComponentA is flagged this way, and it always shows up expanded by default.

    You can also put that attribute directly on a field/property to force that specific instance to be expanded by default;

    Code (csharp):
    1. [Expandable(true)]
    2. public Camera myCamera;
    It works on any item, list or dictionary included.
     
  37. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    The version 1.31 is now available in the Asset Store with the following changes;

    • Added a type-check when displaying an object label to see if the type overload ToString, so it would be called only if a proper implementation exist, and not the base one.
    • Inspector Level and Sorting are now saved in EditorPrefs.
    • Expansion state are now saved in EditorPrefs.
    • Dragging a label to another label automatically performs a copy-paste of that field.

     
  38. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    The version 1.32 s now available on the Asset Store with the following changes;
    • Fixed undo issue with restricted field.
    • Fixed undo issue with struct such as Vector, Quaternion, Bound, Rect, RectOffset.
    • Fixed undo issue with string.
    • Added some shading to the expandable boxes.
    • Added the GameObject/Component picker tool.



    Running out of ideas... So if someone want some feature in the Inspector, now is a great time to ask. :p
     
  39. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    I think the usage instructions are the biggest weakness currently. I still find it a bit confusing on how to do things. Perhaps it can be simplified or better explained in the manuals. Or even a video tutorial could be made. :)
     
  40. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I'm all for better documentation. I thought of making video tutorial, but since my spoken English is... well... not so good, I'm not sure how good it would come out. I thought of making written tutorials, but I simply have no idea where I could publish them, and I'm sure if bloating the packages with tutorials would be a good idea. I don't think Unity's forum would be welcoming of package tutorials. I'm all open for new ideas on how all this could be improved!

    Do you have any specific point in the documentation that you feel is not well explained? Would help if I knew there was specific items in need to refining.

    You can also mail me anytime you wish, and I would be pleased to explain how to do specific things.
     
  41. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    I think that the biggest confusion for me is the lack of UnityScript documentation. It's a shame that some of us were raised on UnityScript and haven't yet mastered C#(!) but some UnityScript examples alongside the C# examples in the manual would be incredibly helpful to me personally.

    Another thing that confuses me sometimes in the manual is that some of the language sometimes is a bit too technical, for example…

    "The base abstract class ComponentMonoBehaviour is an important part of the composition/sub- component pattern. You should never apply the CreateDerive attribute on a field or property that does not derive from ComponentMonoBehaviour, otherwise your object will revert to the field type on the next serialization reload."

    Pardon? :oops: A lot of the manual is written like that. I'm sure it's the correct terminology and a lot of people will understand it but I struggle with it sometimes, and I've been learning programming for a few years now! You're not the only Asset Store author who writes like this though, but maybe the manual can be written in a more general layman manner and include the technical language for the more advanced users in sub-sections.

    I would personally not mind if there was an extra pdf included in the package that was aimed at people like me, with simplified language and a walk-through written tutorial on how to use it.

    The rest of the manual is well documented though, and is impressively illustrated with lots of good screenshots! That side of it is certainly excellent.
     
  42. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I'm sorry about that, but I have very little experience with UnityScript, so translating the whole documentation could take a long while, or even be inaccurate. However, from what I see, it's usually just a matter of syntax... So even if the doc is in C#, you should still be able to decipher it somehow.

    I see what you mean. I guess it's the issue with terminology, if I use other words, they won't be as accurate and someone could get confuse. On the other hand, proper terminology is not easily accessible.

    Now, that is something I could do, even if I somewhat expected the 18 example classes in package to be helpful in that matter.

    Do you have some ideas of what topic would be more useful for such tutorials?
     
  43. Essential

    Essential

    Joined:
    Sep 8, 2011
    Posts:
    265
    Yeah, I have used the example scripts to some success, but it's less than ideal; it's a bit like using them as a rosetta stone to translate the main document, if you know what I mean? But yeah, a separate tutorial would be much more useful!

    I'm not sure of what the tutorial could focus on, but it should be a serialized data object that could be useful in common game development (perhaps an object that keeps track of all enemy data, level data, or item data in an RPG; something which can show off as many features of Adv. Ins. as possible in one project). I think the ideal tutorial approach would be to build it a step at a time, beginning by showing how to display a few simple variables, then slowly adding features such as sliders, colors, dynamic attributes, etc. so the reader can learn how to utilize as many features as possible.

    I think this would also be great marketing for the plugin, as you can show off what kind of an advanced project can be done with Advanced Inspector. And if this written tutorial included both UnityScript and C# code, then the existing manual pdf should ultimately be a lot more easily understandable for UnityScript users as well, as we will have learned the differences in syntax from this tutorial.

    If you go ahead in trying the idea I will be happy to help test out the resulting tutorial.
     
  44. mboog12

    mboog12

    Joined:
    Oct 4, 2011
    Posts:
    91
    hello, i'm having some issues with advanced inspector.

    I have this code in a script
    Code (CSharp):
    1. [Inspect]
    2. private Priority priority = Priority.Normal;
    In editor I set the priority to be Priority.High , but after I press play the priority resets back to Priority.Normal.
    If I change the code to the classic
    Code (CSharp):
    1. [SerializeField]
    2. private Priority priority = Priority.Normal;
    this works as I want and it won't change back to Normal after pressing play.

    Halp please :)
     
  45. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Private field are not serialized - saved - by Unity by default. The Advanced Inspector does not change any of Unity's serialization. Unlike Unity's Inspector, what the Advanced Inspector displays is not limited or linked to what is saved.

    In other words, the Advanced Inspector has no issue displaying items Unity is not saving.

    You have two ways to make the Advanced Inspector display your private field while having it saved by Unity;

    Code (CSharp):
    1.     [AdvancedInspector(InspectDefaultItems = true)]
    2.     public class MyClass
    3.     {
    4.         [SerializeField]
    5.         private Priority priority = Priority.Normal;
    6.     }
    The "InspectDefaultItems" makes Advanced Inspector display all the items the same way Unity would without the need to flag your items with "Inspect". Meaning everything that Unity save would show up. This is the fast and easy way to convert a class to work with the Advanced Inspector.

    Otherwise you can force items to be displayed as;

    Code (CSharp):
    1.     [AdvancedInspector]
    2.     public class MyClass
    3.     {
    4.         [SerializeField, Inspect]
    5.         private Priority priority = Priority.Normal;
    6.     }
    You are not limited to a single attribute by item. Here's an example of a field with multiple attributes;

    Code (CSharp):
    1.     [SerializeField, Inspect, Group("Gameplay"), Descriptor(1f, 0.8f, 0.25f, Name = "NPC Weapons")]
    2.     private WeaponType weapon;
    The fact that Unity's Inspector only display items Unity is able to save is great for new comers. It makes it easy to do the relationship between what is saved and what is displayed.

    However, when you go a bit further, and you need to display debug info, stuff not saved, properties, custom type and so on, Unity usually asks you to write your own custom editor, which is a major waste of time.

    For this task, the Advanced Inspector display item by reflection. It is completely disconnected from what is saved or not saved. So it is up to you to make sure that your items are saved properly following Unity's rules;

    - public fields are saved, unless flagged with NonSerialized.
    - private/protected fields are not saved, unless flagged with SerializeField.
     
    Last edited: Aug 6, 2014
  46. mboog12

    mboog12

    Joined:
    Oct 4, 2011
    Posts:
    91
    Wow, nice.
    Works like a charm, thank you!
     
  47. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    My pleasure.

    Don't hesitate if you have other issues.
     
  48. Mishaps

    Mishaps

    Joined:
    Nov 28, 2011
    Posts:
    181
    with lists is there any way to hide the re-order and remove buttons? artists accidentally re-ordering and deleting items too easily...

    thanks.
     
  49. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Size attribute removes the "-" button and prevents creating or removing items from a list. It forces a collection to be of a fixed length.

    The following leaves the size of the array to be controlled by your own code;
    Code (CSharp):
    1.         [Size]
    2.         public int[] myArray = new int[10];
    Or you can force a collection to be of a fixes size directly from the attribute;
    Code (CSharp):
    1.         [Size(10)]
    2.         public List<int> myArray;
    Also note that if they delete an item by accident, they can undo it with CTRL+Z. However, there's a bug on an undo where the Inspector is not properly refreshed, but the item is really properly undo'ed. Re-selecting the object show the undo happened.

    As of version 1.32, there is no way to remove the re-ordering control. I'm noting this for 1.33.
     
  50. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Just checked back, and yes, you can remove the ordering control with the Size attribute. You have a "Sortable" property in it that removes the control to sort a collection.

    My bad. I will probably rename that Size attribute for something more fitting.