Search Unity

Advanced Inspector - Never Write An Editor Again

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

  1. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    Hi, I've some questions,

    1.
    It seems that the vertical separator line would reset its position whenever a recompile is triggered, is there some way to stop it from snaping back to default position?

    2.
    I tried adding [Inspect] attribute on a method returning IEnumerator, and the method is not called when the button is clicked in inspector?
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    1. It not currently being saved and reloaded. I could save it, or expose a default position in the preferences.

    2. It works fine here, I just tried;
    Code (CSharp):
    1.         [Inspect]
    2.         private IEnumerator Test()
    3.         {
    4.             print("Test");
    5.             return null;
    6.         }
    Can you provide me with an example of a method that doesn't work?
     
  3. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    It'd be best to be able to persist across recompilation, with EditorPrefs maybe?

    Of course,
    Code (CSharp):
    1.         [Inspect]
    2.         public IEnumerator H()
    3.         {
    4.             Debug.Log("hh");
    5.             yield return 0;
    6.         }
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I have a feeling the issue here is the "yield", since the IEnumator isn't really returned. Do you really need that yield, since it's not a coroutine?
     
  5. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    Indeed I'm writing coroutines for some procedural generation code that will last multiple frames.

    and I need to test it a lot in edit-mode, a trigger button would be handy here.

    It would be very helpful If A.I. could detect a coroutine and deal with it.
    If that's difficult to handle, I could do with an extra method or a custom editor, not a big deal anyway. :)

    Code (CSharp):
    1.         public IEnumerator H()
    2.         {          
    3.             Debug.Log("step1");
    4.             yield return 0;
    5.             Debug.Log("step2");
    6.             yield return 0;
    7.             Debug.Log("step3");
    8.         }
    9.  
    10.         [Inspect]
    11.         public void DoH()
    12.         {
    13.             var a = H();
    14.             while (a.MoveNext()) ;
    15.         }
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I'm all ears if you have an idea about how to handle coroutines in editor mode. As far as I know, only MonoBehaviour handles those and usually when the game is actually running.

    I could create a hidden/non-saveable GameObject, add a [ExecuteInEditMode] MonoBehaviour (not even sure if those execute coroutines in edit mode) on it and ask it to run the coroutines. However, I have no way to know if it's actually a coroutine and not simply a method returning an IEnumerator (no real way to know if there's a yield statement in it). I could always add a "IsCoroutine" property in the Method Attribute.

    EDIT: That doesn't work. Looking for other potential solution.
     
    Last edited: May 29, 2016
  7. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    Not a reflection guru, so I can not say for sure if there's a way to tell if a method has yield return inside.

    But I think a [IsCoroutine] attribute could do in this case, if A.I. could internally call the coroutine to get the IEnumerator and call MoveNext() repeately.
    This would work in edit-mode too.

    Code (CSharp):
    1.     [Inspect]
    2.         public void DoH()
    3.         {
    4.             var a = H();
    5.             while (a.MoveNext()) ;
    6.         }

    Oh, by the way, there is another suggestion of feature:

    It would be also very helpful to be able to call a method with parameter (in most case, one parameter will do).
    For example,
    1. click a button on inspector;
    2. an editorwindow is popup to prompt a (int/bool/string/float) parameter;
    3. click "OK" to invoke the method with parameter;
     
  8. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It's a tiny bit more complex... Currently, this is working and is also handling WaitForSeconds. (WaitForFrame is pointless in editor mode). Also, since the current version of AI is for 5.2, there is no CustomYieldInstruction or nesting of IEnumerator.

    Code (CSharp):
    1. namespace AdvancedInspector
    2. {
    3.     [InitializeOnLoad]
    4.     internal class InspectorCoroutine
    5.     {
    6.         private static List<IEnumerator> coroutines = new List<IEnumerator>();
    7.  
    8.         private static Dictionary<WaitForSeconds, DateTime> timers = new Dictionary<WaitForSeconds, DateTime>();
    9.  
    10.         private static FieldInfo waitForSecondTime;
    11.  
    12.         static InspectorCoroutine()
    13.         {
    14.             EditorApplication.update += Update;
    15.  
    16.             waitForSecondTime = typeof(WaitForSeconds).GetField("m_Seconds", BindingFlags.NonPublic | BindingFlags.Instance);
    17.         }
    18.  
    19.         public static void StartCoroutine(IEnumerator routine)
    20.         {
    21.             routine.MoveNext();
    22.             coroutines.Add(routine);
    23.         }
    24.  
    25.         private static void Update()
    26.         {
    27.             for (int i = coroutines.Count - 1; i >= 0; i--)
    28.             {
    29.                 IEnumerator enumerator = coroutines[i];
    30.                 WaitForSeconds waitForSeconds = enumerator.Current as WaitForSeconds;
    31.                 if (waitForSeconds != null)
    32.                 {
    33.                     if (timers.ContainsKey(waitForSeconds))
    34.                     {
    35.                         float time = (float)waitForSecondTime.GetValue(enumerator.Current);
    36.                         TimeSpan span = DateTime.Now - timers[waitForSeconds];
    37.                         if (span.TotalSeconds < time)
    38.                             continue;
    39.  
    40.                         timers.Remove(waitForSeconds);
    41.                     }
    42.                     else
    43.                     {
    44.                         timers.Add(waitForSeconds, DateTime.Now);
    45.                         continue;
    46.                     }
    47.                 }
    48.  
    49.                 if (!enumerator.MoveNext())
    50.                     coroutines.RemoveAt(i);
    51.             }
    52.         }
    53.     }
    54. }
    55.  
    Honestly, it's not a feature I would add in AI, since it's something you can do already with existing AI features.

    Here's an example requiring no new features and no reflection;

    Code (CSharp):
    1.         [Inspect, RuntimeResolve]
    2.         private object parameter;
    3.  
    4.         private Type type;
    5.  
    6.         [Inspect, Expandable(false), Restrict("GetTypes")]
    7.         private Type Type
    8.         {
    9.             get { return type; }
    10.             set
    11.             {
    12.                 if (type == value)
    13.                     return;
    14.  
    15.                 type = value;
    16.                 if (type == typeof(bool))
    17.                     parameter = false;
    18.                 else if (type == typeof(int))
    19.                     parameter = 0;
    20.                 else if (type == typeof(float))
    21.                     parameter = 0f;
    22.             }
    23.         }
    24.  
    25.         [Inspect]
    26.         private void Invoke()
    27.         {
    28.             if (type == typeof(bool))
    29.                 MethodWithBool((bool)parameter);
    30.             else if (type == typeof(int))
    31.                 MethodWithInt((int)parameter);
    32.             else if (type == typeof(float))
    33.                 MethodWithFloat((float)parameter);
    34.         }
    35.  
    36.         private IList GetTypes()
    37.         {
    38.             return new Type[] { typeof(bool), typeof(int), typeof(float) };
    39.         }
    40.  
    41.         private void MethodWithBool(bool value)
    42.         {
    43.             print("This is a boolean : " + value);
    44.         }
    45.  
    46.         private void MethodWithInt(int value)
    47.         {
    48.             print("This is a integer : " + value);
    49.         }
    50.  
    51.         private void MethodWithFloat(float value)
    52.         {
    53.             print("This is a float : " + value);
    54.         }
     
  9. TMPxyz

    TMPxyz

    Joined:
    Jul 20, 2012
    Posts:
    766
    Hmm, never mind, that was just some of my random thought. I will handle it.

    Well, just something I thought it would be great to have, forget it.
     
  10. Astro75

    Astro75

    Joined:
    Dec 18, 2014
    Posts:
    48
    I think I've found a bug. I have a List of prefab references in another prefab. Select prefab with an empty list. Lock the inspector. Select more than one prefab and drag to that list. It shows that they are in the list. But when I save it does nothing (List resets after unity restart).
     
  11. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Mind showing the snippet of code of that list?
     
  12. AVOlight

    AVOlight

    Joined:
    Apr 15, 2014
    Posts:
    427
    has the latest build been tested in 5.3.5 ?
    some reason my normal [Inspect] ed fields are showing up as readonly ? and other weird stuff...
     
  13. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
  14. AVOlight

    AVOlight

    Joined:
    Apr 15, 2014
    Posts:
    427
    ReflectionTypeLoadException: The classes in the module cannot be loaded.

    i'll try out the new patch 5.3.5p2,

    ---

    yea p2 has the same thing; i'll go back to 5.3.4

    ---

    getting the same thing in 5.3.4p6
     
    Last edited: Jun 10, 2016
  15. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Can you show me the whole assert callstack? Maybe a screenshot of the inspector with a snippet of code?
     
  16. AVOlight

    AVOlight

    Joined:
    Apr 15, 2014
    Posts:
    427
    Is this ok?

    ReflectionTypeLoadException: The classes in the module cannot be loaded.
    Assembly.GetTypes()
    AdvancedInspector.FieldEditor.CollectFieldEditors()
    AdvancedInspector.InspectorEditor.OnEnable()
    AdvancedInspector.BehaviourEditor.OnEnable()

    ---

    Turns out to be a conflict with some of my more complex classes that inherit from abstract generic nested classes... ( havent been able to replicate the issue in the last 30ish mins...)

    that experiment won't require smart inspectors so i'll separate it out from this project

    btw working great for me in 5.3.5.p3, (I only use for Inspectors, no custom editor windows)
     
    Last edited: Jun 11, 2016
  17. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Well, if you want to send me your "experiment", I could try to find out what's going on.
     
    AVOlight likes this.
  18. AVOlight

    AVOlight

    Joined:
    Apr 15, 2014
    Posts:
    427
    @LightStriker Thanks for the support, but its alright i've just removed it
     
  19. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    I'm having an issue since updating to the newest Asset store build.

    TypeLoadException: Could not load type 'AdvancedInspector.IgnoreBase' from assembly 'Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
    AdvancedInspector.InspectorField.GetEntries (AdvancedInspector.InspectorField parent, System.Object[] instances, Boolean inspectDefaultItems, Boolean bypass) (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorField.cs:3282)
    AdvancedInspector.InspectorField.GetEntries (AdvancedInspector.InspectorField parent, System.Object[] instances, Boolean inspectDefaultItems) (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorField.cs:3188)
    AdvancedInspector.InspectorEditor.RefreshFields () (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:464)
    AdvancedInspector.InspectorEditor.set_Instances (System.Object[] value) (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:104)
    AdvancedInspector.InspectorEditor.OnEnable () (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:193)
    AdvancedInspector.BehaviourEditor.OnEnable () (at C:/Users/LightStriker/Desktop/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditors/BehaviourEditor.cs:34)
     
  20. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Can you check that you properly have the file "IgnoreBase.cs"?

    Also, that your game code compile properly? You don't have any compilation error?
     
  21. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Version 1.68 have been submitted for review to the Asset Store.

    Changelist;

    1.68
    [CHANGES]
    • The Method attribute has a new property named "IsCoroutine", which allows you to invoke coroutines in the editor. WaitForSeconds is supported, but not YieldCustom.
    • Added preferences control over the default and playmode color of the inspector boxing, since we cannot access the Unity's one.
    • FieldAttribute added, an attribute-bound FieldEditor. It is like PropertyDrawer, but with far less limitation. See the documentations and examples.
    [FIXES]
    • Support Unity 5.4;
    • Removed some advanced and debug properties from the Animator inspector; Unity had the brilliant idea of spamming warning everytime they are inspected.
    • Update Renderes editor for the new 5.4 features.
    • Disable contextual collection control when read only.
    • Allows custom EditorField being used with CreateDerived fields.
    • Prevent drag'n'dropping ComponentMonoBehaviour on other fields.
    • Fixed an issue where some properties without a setter would not appear as read only.
    • Internal Change; InspectorField.Editor now returns the associated FieldEditor if any.
    • Allow to ping the script from a ComponentMonoBehaviour by clicking on it.

    Now the big change here is the FieldAttribute base type.

    I never hid my dislike for the PropertyDrawer class which is serialization bound. Which mean, it cannot be applied - as an Attribute-bound drawer - to non-serialized members. Or that it cannot support GUILayout or that you have to manually calculate its "height".

    Someone came to me...

    Sounds simple enough, no? To make a single non-editable label that doesn't hide the name of the member?

    The FieldEditor is a powerful class that allows you to do a lot of thing PropertyDrawers can't; draw property or field even if they are not serialized, use Unity's Layouting, drive the behaviour of the label's contextual menu and much more.

    But until now, there was no easy way to invoke one like the attribute-bound PropertyDrawer could.

    So here's the solution;

    Code (CSharp):
    1.     public class AIExample42_FieldAttribute : MonoBehaviour
    2.     {
    3.         [Inspect, FieldAttributeExample]
    4.         private string Text
    5.         {
    6.             get { return "This is some non-serialized property text"; }
    7.         }
    8.     }
    Code (CSharp):
    1.     public class FieldAttributeExample : FieldAttribute { }
    Code (CSharp):
    1.     public class FieldAttributeExampleDrawer : FieldEditor
    2.     {
    3.         public override Type[] EditedTypes
    4.         {
    5.             get { return new Type[] { typeof(FieldAttributeExample) }; }
    6.         }
    7.  
    8.         public override void Draw(FieldAttribute attribute, InspectorField field)
    9.         {
    10.             object value = field.GetValue();
    11.             if (value == null)
    12.                 return;
    13.  
    14.             GUILayout.Label(value.ToString());
    15.         }
    16.     }
    Which gives;



    Simple enough, I hope. Can be applied to fields, properties and methods, serialized or not.
     
    Last edited: Jun 18, 2016
  22. PedroGV

    PedroGV

    Joined:
    Nov 1, 2010
    Posts:
    415
    I'd like to thank @LightStriker for this update and for his support. All the features packed in v1.68 do indeed fit my coding needs. Support for v5.4.x, FieldAttribute class (with it I can avoid marking fields as ReadOnly and the nasty grayout), configuring colours for design and runtime on AI's properties. picking the file associated to a ComponentMonoBehaviour by clicking on it on the Inspector, to mention just a few.

    I'll be writing a five-star review for it shortly after it gets released and, of course, I really recommend you guys download and test it asap.
     
  23. TurboNuke

    TurboNuke

    Joined:
    Dec 20, 2014
    Posts:
    69
    Hi,
    Is there any way I can add extra context menu options to lists of items?
    I would like to add a bunch of sort functions to sort the original list in different ways.
    Cheers.
     
  24. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Yes it's possible.

    You can look at the file VectorEditor.cs. It has an overloaded method named "OnContextualClick".
     
  25. TurboNuke

    TurboNuke

    Joined:
    Dec 20, 2014
    Posts:
    69
    Ah no sorry, I dont mean on the individual items, that's a great feature which I already use.
    I mean on the list itself.
    I've tried adding an editor for Lists but I seem to break things when I do that.
     
  26. plundo

    plundo

    Joined:
    Mar 16, 2013
    Posts:
    4
    Hey,

    I've found a 3rd party plugin that causes issue with the built in unity 'range' header...

    I can only get it working if I update it to a 'RangeValue', and add the 'using AdvancedInspector' line.


    [Range(0f,1f)]
    public float weighting=1;

    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.RangeDrawer.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at /Users/builduser/buildslave/unity/build/Editor/Mono/ScriptAttributeGUI/Implementations/PropertyDrawers.cs:15)
     
  27. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Ah... No, I guess not right now. I'll have to figure out something.

    Which plugin?
     
  28. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Hello! I have created an improved Button class that adds more events to the default Unity-Button component. The class inherits from Button and I believe Unity is applying a custom inspector to it. Is it possible to use Advanced Inspector to draw what the default inspector drawer would do? The class is very short and all I want to do is expose the new Unity events to the inspector.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.UI;
    4. using UnityEngine.Events;
    5. using UnityEngine.EventSystems;
    6. using System.Collections;
    7. using System;
    8. using AdvancedInspector;
    9.  
    10. [AdvancedInspector]
    11. public class AdvancedButton : Button
    12. {
    13.     #region Events
    14.  
    15.     [Inspect]
    16.     public UnityEvent onMouseUpAsButton = new UnityEvent ();
    17.  
    18.     public UnityEvent onMouseUp = new UnityEvent ();
    19.  
    20.     public UnityEvent onMouseOver = new UnityEvent ();
    21.  
    22.     public UnityEvent onMouseExit = new UnityEvent ();
    23.  
    24.     public UnityEvent onMouseEnter = new UnityEvent ();
    25.  
    26.     public UnityEvent onMouseDrag = new UnityEvent ();
    27.  
    28.     public UnityEvent onMouseDown = new UnityEvent ();
    29.  
    30.     #endregion
    31.  
    32.  
    33.  
    34.     #region Main Methods
    35.  
    36.     public void OnMouseUpAsButton ()
    37.     {
    38.         onMouseUpAsButton.Invoke ();
    39.     }
    40.  
    41.     public void OnMouseUp ()
    42.     {
    43.         onMouseUp.Invoke ();
    44.     }
    45.  
    46.     public void OnMouseOver ()
    47.     {
    48.         onMouseOver.Invoke ();
    49.     }
    50.  
    51.     public void OnMouseExit ()
    52.     {
    53.         onMouseExit.Invoke ();
    54.     }
    55.  
    56.     public void OnMouseEnter ()
    57.     {
    58.         onMouseEnter.Invoke ();
    59.     }
    60.  
    61.     public void OnMouseDrag ()
    62.     {
    63.         onMouseDrag.Invoke ();
    64.     }
    65.  
    66.     public void OnMouseDown ()
    67.     {
    68.         onMouseDown.Invoke ();
    69.     }
    70.  
    71.     #endregion
    72. }
    73.  
     
  29. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    I tried adding the Inspect command but the Inspector did not update to show the property. I figured I'd ask if I can actually override the custom inspector before I got too deep into making it work.
     
  30. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Which is normal, since Unity created a custom inspector in between your class and Advanced Inspector's own. Which mean, the closest one to your type take priority, and it's not something we can override. It's a Unity feature we have no control over.

    In the version 1.67, we added an example of overriding Unity's button class by simply adding a sound clip field to be played when pressing a button. It's called "SoundButton". It's not a short example, as sadly, there is no easy way to do that. It's one of the big disadvantage of Unity having hand-made inspector for all their classes.

    Surprisingly, the ButtonEditor is not internal. So you could call it before AI's drawing like this;

    Code (CSharp):
    1.     [CanEditMultipleObjects]
    2.     [CustomEditor(typeof(AdvancedButton), true)]
    3.     public class AdvancedButtonEditor : InspectorEditor
    4.     {
    5.         public override void OnInspectorGUI()
    6.         {
    7.             Editor editor = CreateEditor(targets, typeof(ButtonEditor));
    8.             editor.OnInspectorGUI();
    9.  
    10.             base.OnInspectorGUI();
    11.         }
    12.     }
    Obviously, the stuff drawn by ButtonEditor won't have any Advanced Inspector features.
     
  31. plundo

    plundo

    Joined:
    Mar 16, 2013
    Posts:
    4
    Plugin is called Easy AI Steer.
     
  32. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Have you contacted the author?
    Would it be that they have a Range class that is not namespaced? Like, if you do [UnityEngine.Range(0, 1)], does it work?
     
  33. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    Thank you
     
  34. XaneFeather

    XaneFeather

    Joined:
    Sep 4, 2013
    Posts:
    98
    Hello! I've been wondering if there is an option to make collections always expanded, akin to the "AlwaysExpanded" property of the "Expandable" attribute but for the collection itself rather than its items.
     
  35. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Not right now, but it has been requested. It will probably be a property of the Collection attribute.
     
  36. XaneFeather

    XaneFeather

    Joined:
    Sep 4, 2013
    Posts:
    98
    That'd be most appreciated! Also, I think I found a small bug. When a property is set to "AlwaysExpanded", you can still open and collapse it by double-clicking the label.

     
  37. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    All hail a working forum! :)
     
  38. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    It looks like the new FieldAttribute when used on a Collection behaves differently than defining a FieldEditor for the field. I have a list of int that I treat as lookups, and when I use the FieldEditor attribute it lets me edit each int as it's own object and "GetField" returns one int. With the FieldAttribute set GetField returns the whole collection instead.
     
  39. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It's totally normal, as the FieldAttribute is not an IListAttribute, so it's not passed-down to the element of a collection.

    Otherwise, how would you apply a FieldAttribute to a collection?
    The work around should be fairly simple, you just have to implement the IListAttribute interface on your own FieldAttribute.
     
  40. XaneFeather

    XaneFeather

    Joined:
    Sep 4, 2013
    Posts:
    98
    Now, this is only a very minor thing but is there a way to make a Title/Header appear with reduced left padding compared to the item it is over? The titles in groups currently seem to have even more left padding than the items themselves.

     
  41. Zireael07

    Zireael07

    Joined:
    Apr 27, 2016
    Posts:
    47
    Can I use custom inspector scripts with this? Specifically, I'm using 'Transform Inspector with Size' from the Unify wiki.
     
  42. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    How do I make this work? If I implement that interface (no actual difference in the attribute?) how do I ensure it applies to the items IN the collection rather than the whole thing?

     
  43. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    That's the purpose of this interface. It's an empty interface, but AI take any attribute that implement it, and apply it to the items of a collection instead of the collection itself.
     
  44. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Of course. The package comes with numerous custom editors that override Unity's own. You can modify the TransformEditor.cs to add or remove any features you need.

    For example, the TransformEditor looks like this;

    Code (CSharp):
    1.     public class TransformEditor : InspectorEditor
    2.     {
    3.         protected override void RefreshFields()
    4.         {
    5.             Type type = typeof(Transform);
    6.  
    7.             fields.Add(new InspectorField(type, Instances, type.GetProperty("localPosition"),
    8.                 new DescriptorAttribute("Position", "Position of the transform relative to the parent transform.", "http://docs.unity3d.com/ScriptReference/Transform-localPosition.html")));
    9.             fields.Add(new InspectorField(type, Instances, type.GetProperty("localEulerAngles"),
    10.                 new DescriptorAttribute("Rotation", "The rotation of the transform relative to the parent transform's rotation.", "http://docs.unity3d.com/ScriptReference/Transform-localRotation.html")));
    11.             fields.Add(new InspectorField(type, Instances, type.GetProperty("localScale"),
    12.                 new DescriptorAttribute("Scale", "The scale of the transform relative to the parent.", "http://docs.unity3d.com/ScriptReference/Transform-localScale.html")));
    13.  
    14.             fields.Add(new InspectorField(type, Instances, type.GetProperty("position"), new InspectAttribute(InspectorLevel.Advanced),
    15.                 new DescriptorAttribute("World Position", "The position of the transform in world space.", "http://docs.unity3d.com/ScriptReference/Transform-position.html")));
    16.             fields.Add(new InspectorField(type, Instances, type.GetProperty("rotation"), new InspectAttribute(InspectorLevel.Advanced),
    17.                 new DescriptorAttribute("World Rotation", "The rotation of the transform in world space stored as a Quaternion.", "http://docs.unity3d.com/ScriptReference/Transform-rotation.html")));
    18.         }
    19.     }
    Instead of trying to draw manually everything, with AI you simply give it a list of the items you wish to inspect. In this case, I also added a tooltip and a URL towards Unity's documentation to each item. I also added the world position and world orientation that shows up only when in advanced or debug mode.

    Now, in 99.99% of the time, you don't have to do any of this. You can simply add attributes directly to your members (fields, properties, methods) and AI will parse and inspect them without any need to write a custom editor.

    AI also give priority to any other custom editor it finds. For example, if you buy an asset store package and it comes with a custom editor, that editor takes priority.
     
    Last edited: Jul 13, 2016
    Zireael07 likes this.
  45. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    When I add IListAttribute to my attribute it still tries to call the field editor for the collection, not just the contents of the collection. When FieldAttribute is set the list doesn't call into the field editor, only the contents.
     
  46. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Odd, I'll check it out.
     
  47. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    You're right, there was a bug.

    Contact me at admin@lightstrikersoftware.com if you want a version with this issue fixed.
     
  48. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    No worries, for the moment I'll leave it using the FieldEditor, I'll wait for it to show up in a patch :)
     
  49. Miguel-Ferreira

    Miguel-Ferreira

    Joined:
    May 8, 2015
    Posts:
    90
    Hi,
    Loving you asset, just a quick doubt; is it possible to inspect a method with params? It would be pretty neat to be able to generate a button + params for a method with the [Inspect] attribute, just like how https://github.com/vexe/VFW does.
     
    Last edited: Jul 15, 2016
  50. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I've read that page, and can't find any mention of displaying methods with params. What it looks like? Could you have a screenshot of how it draws the methods?

    It sure would be possible, even if I'm not sure how I would organize that visually.