Search Unity

Advanced Inspector - Never Write An Editor Again

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

  1. BehemothPro

    BehemothPro

    Joined:
    Feb 14, 2015
    Posts:
    19
    I've been trying to make my own FieldEditor for UnityEvents but it doesn't seem to be able to detect it's type.
    I've tried this:
    Code (csharp):
    1. public override Type[] EditedTypes
    2. {
    3.   get { return new Type[] { typeof(UnityEventBase),  typeof(UnityEvent) }; }
    4. }
    but it doesn't work. What am I doing wrong?
     
  2. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Simply that there's a Property Drawer assigned to that specific type - UnityEvent.

    For backward compatibility purpose, type-bound Property Drawers have an higher priority than the Field Editor.

    Also, from someone who tried to write his own Field Editor for UnityEvent - and failed - this is a very hard job as everything in it is private or internal.

    It could help to know the result you're seeking?
     
  3. BehemothPro

    BehemothPro

    Joined:
    Feb 14, 2015
    Posts:
    19
    My intent was to make the fields not so crunched up horizontally so I could clearly see the run type, object, and function name fields. Then I was going to add functionally to optionally only show certain functions that I wanted to show by placing a custom attribute on those functions.

    o lol, is it really that annoying to deal with? Then would you say it's better to make my own version of UnityEvent instead?
     
  4. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Most likely that it would be less painful.
     
  5. electroflame

    electroflame

    Joined:
    May 7, 2014
    Posts:
    177
    Any chance I could get an advance copy of 1.56? I just upgraded to 5.1 and much of the AdvancedInspector stuff is now rendering as a dark, purplish color (presumably due to the issue you mentioned).
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Sure, send me a mail at admin@lightstrikersoftware.com
     
  7. electroflame

    electroflame

    Joined:
    May 7, 2014
    Posts:
    177
    Sent you an email. Thanks!

    EDIT: Got it. Thanks for the quick reply!
     
    Last edited: Jun 11, 2015
  8. yano_123

    yano_123

    Joined:
    Aug 24, 2012
    Posts:
    41
    I have one request. Could you add an attribute to hide Script Field if possible? Thanks.
     
  9. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    It already exist; check the [AdvancedInspector] attribute, there's a property to hide the script field.
     
  10. yano_123

    yano_123

    Joined:
    Aug 24, 2012
    Posts:
    41
    Hi, I overlooked that. Thank you very much!
     
  11. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    1.56 is now available on the store.
     
  12. Zoey_O

    Zoey_O

    Joined:
    Mar 15, 2013
    Posts:
    28
    Code (CSharp):
    1. using UnityEngine;
    2. using AdvancedInspector;
    3.  
    4. [AdvancedInspector(false, true)]
    5. public class TestBehaviour : MonoBehaviour {
    6.  
    7.     private TestEnum _value;
    8.    
    9.     [Inspect]
    10.     public TestEnum Value
    11.     {
    12.         get { return _value; }
    13.     }
    14. }
    15.  
    16. public enum TestEnum : byte
    17. {
    18.     A = 1,
    19.     B = 20,
    20.     C = 67
    21. }
    Using this code I get this error in the inspector:

    InvalidCastException: Cannot cast from source type to destination type.
    AdvancedInspector.EnumEditor.Draw (AdvancedInspector.InspectorField field, UnityEngine.GUIStyle style) (at Assets/Plugins/Editor/AdvancedInspector/FieldEditors/EnumEditor.cs:39)
    AdvancedInspector.AdvancedInspectorControl.DrawField (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField field, UnityEditor.PropertyDrawer properyDrawer, AdvancedInspector.FieldEditor fieldEditor, UnityEngine.GUIStyle style)

    I do not get the error if I remove the underlying type of the enum (which is byte). Works fine with int (which I believe is the default when not specified). I have a 3rd party enumeration that is declared as a byte that is giving me this issue.
     
  13. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Sorry for that, just never tested byte enums.

    You can fix it by replacing the file EnumEditor.cs with this;

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using System.Linq;
    7.  
    8. namespace AdvancedInspector
    9. {
    10.     public class EnumEditor : FieldEditor
    11.     {
    12.         public override bool EditDerived
    13.         {
    14.             get { return true; }
    15.         }
    16.  
    17.         public override bool Expandable
    18.         {
    19.             get { return false; }
    20.         }
    21.  
    22.         public override Type[] EditedTypes
    23.         {
    24.             get { return new Type[] { typeof(Enum) }; }
    25.         }
    26.  
    27.         public override void Draw(InspectorField field, GUIStyle style)
    28.         {
    29.             EnumAttribute display = field.GetAttribute<EnumAttribute>();
    30.  
    31.             EditorGUI.showMixedValue = field.Mixed;
    32.  
    33.             EditorGUI.BeginChangeCheck();
    34.  
    35.             object result = null;
    36.             long value = Convert.ToInt64(GetValue(field));
    37.             if (display == null || !display.Masked)
    38.             {
    39.                 if (display == null || display.Display == EnumDisplay.DropDown)
    40.                     result = DrawDropDown(field.Type, value, style, false);
    41.                 else if (display.Display == EnumDisplay.Button)
    42.                     result = DrawEnum(field.Type, value, display.MaxItemsPerRow, style == null ? EditorStyles.toolbarButton : style);
    43.                 else if (display.Display == EnumDisplay.Checkbox)
    44.                     result = DrawEnum(field.Type, value, display.MaxItemsPerRow, style == null ? EditorStyles.toggle : style);
    45.             }
    46.             else
    47.             {
    48.                 if (display == null || display.Display == EnumDisplay.DropDown)
    49.                     result = DrawDropDown(field.Type, value, style, true);
    50.                 else if (display.Display == EnumDisplay.Button)
    51.                     result = DrawMasked(field.Type, value, display.MaxItemsPerRow, style == null ? EditorStyles.toolbarButton : style);
    52.                 else if (display.Display == EnumDisplay.Checkbox)
    53.                     result = DrawMasked(field.Type, value, display.MaxItemsPerRow, style == null ? EditorStyles.toggle : style);
    54.             }
    55.  
    56.             if (EditorGUI.EndChangeCheck())
    57.                 field.SetValue(result);
    58.         }
    59.  
    60.         private int SelectedIndex(Array values, long value)
    61.         {
    62.             for (int i = 0; i < values.Length; i++)
    63.                 if (Convert.ToInt64(values.GetValue(i)) == value)
    64.                     return i;
    65.  
    66.             return 0;
    67.         }
    68.  
    69.         private string[] GetNames(Type type)
    70.         {
    71.             Array values = Enum.GetValues(type);
    72.             List<string> names = Enum.GetNames(type).ToList();
    73.  
    74.             for (int i = 0; i < names.Count; i++)
    75.             {
    76.                 DescriptorAttribute descriptor = ((Enum)values.GetValue(i)).GetAttribute<DescriptorAttribute>();
    77.                 if (descriptor != null && !string.IsNullOrEmpty(descriptor.Name))
    78.                     names[i] = descriptor.Name;
    79.                 else
    80.                     names[i] = ObjectNames.NicifyVariableName(names[i]);
    81.             }
    82.  
    83.             return names.ToArray();
    84.         }
    85.  
    86.         private object DrawDropDown(Type type, long value, GUIStyle style, bool masked)
    87.         {
    88.             string[] names = GetNames(type);
    89.             Array values = Enum.GetValues(type);
    90.  
    91.             if (masked)
    92.             {
    93.                 if (style == null)
    94.                     value = EditorGUILayout.MaskField(Convert.ToInt32(value), names);
    95.                 else
    96.                     value = EditorGUILayout.MaskField(Convert.ToInt32(value), names, style);
    97.  
    98.                 return Enum.ToObject(type, value);
    99.             }
    100.             else
    101.             {
    102.                 int selected = SelectedIndex(values, value);
    103.  
    104.                 if (style == null)
    105.                     selected = EditorGUILayout.Popup(selected, names);
    106.                 else
    107.                     selected = EditorGUILayout.Popup(selected, names, style);
    108.  
    109.                 return Enum.ToObject(type, values.GetValue(selected));
    110.             }
    111.         }
    112.  
    113.         private object DrawEnum(Type type, long value, int max, GUIStyle style)
    114.         {
    115.             if (max < 1)
    116.                 max = 6;
    117.  
    118.             string[] names = GetNames(type);
    119.             Array values = Enum.GetValues(type);
    120.  
    121.             int rows = Mathf.CeilToInt((float)names.Length / (float)max);
    122.             int count = (names.Length / rows);
    123.             if (count * rows < names.Length)
    124.                 count++;
    125.  
    126.             int selected = SelectedIndex(values, value);
    127.  
    128.             GUILayout.BeginVertical();
    129.  
    130.             for (int i = 0; i < rows; i++)
    131.             {
    132.                 GUILayout.BeginHorizontal();
    133.  
    134.                 for (int j = count * i; j < count * (i + 1); j++)
    135.                 {
    136.                     if (j >= names.Length)
    137.                         break;
    138.  
    139.                     if (selected == j)
    140.                         GUILayout.Toggle(true, names[j], style);
    141.                     else if (GUILayout.Toggle(false, names[j], style))
    142.                         selected = j;
    143.                 }
    144.  
    145.                 GUILayout.EndHorizontal();
    146.             }
    147.  
    148.             GUILayout.EndVertical();
    149.  
    150.             return Enum.ToObject(type, values.GetValue(selected));
    151.         }
    152.  
    153.         private object DrawMasked(Type type, long value, int max, GUIStyle style)
    154.         {
    155.             if (max < 1)
    156.                 max = 6;
    157.  
    158.             Array values = Enum.GetValues(type);
    159.             string[] names = GetNames(type);
    160.  
    161.             int rows = Mathf.CeilToInt((float)names.Length / (float)max);
    162.             int count = (names.Length / rows);
    163.             if (count * rows < names.Length)
    164.                 count++;
    165.  
    166.             int result = 0;
    167.  
    168.             GUILayout.BeginVertical();
    169.  
    170.             for (int i = 0; i < rows; i++)
    171.             {
    172.                 GUILayout.BeginHorizontal();
    173.  
    174.                 for (int j = count * i; j < count * (i + 1); j++)
    175.                 {
    176.                     if (j >= names.Length)
    177.                         break;
    178.  
    179.                     int v = (int)values.GetValue(j);
    180.                     if (GUILayout.Toggle(((int)value & v) == v, names[j], style))
    181.                         result |= v;
    182.                 }
    183.  
    184.                 GUILayout.EndHorizontal();
    185.             }
    186.  
    187.             GUILayout.EndVertical();
    188.  
    189.             return Enum.ToObject(type, result);
    190.         }
    191.     }
    192. }
     
  14. Zoey_O

    Zoey_O

    Joined:
    Mar 15, 2013
    Posts:
    28
    That worked perfect, thanks!

    I'm having another issue now. I can't get the AdvancedInspector attribute to work on NetworkBehaviours in Unity 5.1. It works fine if I change the inheriting type to MonoBehaviour. The NetworkBehaviour inherits from MonoBehaviour.
     
  15. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    NetworkBehaviour - and also StateMachineBehaviour - are a prime example of why I sometimes hate people at Unity. One would assume that in the case of a base class - like MonoBehaviour - you wouldn't implement a custom editor because the real definition is derived from it... But they did.

    Now, unlike StateMachineBehaviour - which is a rather empty custom editor and is easy to ignore - the NetworkBehaviour editor appear to have some stuff in it that may be hard to replicate if one would want to make his own custom one on top.
     
    Last edited: Jun 13, 2015
  16. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    Hey LightStriker. Thanks for the asset.

    Is there a way to force a class to use an advanced inspector? I am inheriting from a 3rd party base class that already has an editor class defined for it. I would like to use their editor generally, but for this specific subclass, I'd love to use advanced inspector. Can I annotate my class with something? I haven't found it in the docs yet.

    Edit: To be more specific, the 3rd party class I inherit from has a respective editor class with a [CustomEditor] attribute. I'd like to avoid using that for my specific subclass.

    Thanks!
     
    Last edited: Jun 14, 2015
  17. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    By default, Advanced Inspector is as non-intrusive as possible; meaning it never override an existing custom inspector if one exist for a specific class. It's not very hard because of how Unity decides which custom editor to use when it tries to inspect an object.

    It's implemented in something like this;

    Code (CSharp):
    1.     [CustomEditor(typeof(MonoBehaviour), true)]
    2.     public class BehaviourEditor : InspectorEditor
    3.     {
    4.         // ton of stuff
    5.     }
    In short, it declares to Unity that it wants to inspect everything deriving from MonoBehaviour. However, Unity always pick an editor that is closer to the object's type in the hierarchy chain. It's actually a behaviour from Unity that we simply cannot change.

    Let's say I have;

    Code (CSharp):
    1. public class Enemy : Character { }
    2.  
    3. public class Character : MonoBehaviour { }
    4.  
    5. [CustomEditor(typeof(Character), false)]
    6. public class CharacterEditor : Editor { }
    • If Unity inspect a Character, it would take the CharacterEditor to inspect it because it has a direct declaration.
    • If Unity inspect a Enemy, it would take Advanced Inspector because the CharacterEditor's CustomEditor attribute is flagged as not inspecting derived type. (the false parameter)
    • If for some reason someone wrote this "[CustomEditor(typeof(Character), true)]" instead... If you derive from Character, you will always get the CharacterEditor to inspect your class, unless there's an editor closer to your own type.

    From what you're saying, you're facing the last case where the editor you have is flagged as inspecting all derived type. If so, all is not lost; you only need to declare a closer Editor to your type, like this;

    Code (CSharp):
    1. using AdvancedInspector;
    2. using UnityEditor;
    3.  
    4. [CustomEditor(typeof(Enemy), true)]
    5. public class EnemyEditor : BehaviourEditor { }
    6.  
    It's really that simple to make Advanced Inspector insert itself in the middle of a hierarchy of inspected types. Now, I know I promised that you would never have to write a custom editor ever again... and I keep that promise - kind of - as you only write the declaration of one, and not any logic in it. ;)

    BehaviourEditor is the base type that handles MonoBehaviour. It performs specific tasks related to ComponentMonoBehaviour.

    ScriptableEditor is the base type that handles ScriptableObject. It performs specific tasks related to "InspectorWrapper", a feature that let Advanced Inspector inspect object that does not derive from Unity base class.
     
  18. sballew7

    sballew7

    Joined:
    Sep 3, 2013
    Posts:
    76
    Awesome! Thanks for the tip. I was pretty close, since I picked up on the Editor hierarchy. I had my own editor and was hoping there was a simple class to extend. It is working perfectly now. Thanks, especially for the quick reply!
     
  19. barrenjunk

    barrenjunk

    Joined:
    Jul 10, 2013
    Posts:
    6
    Greetings,
    I'm having problems with collections in 1.56 (Unity 5.1) and was wondering if this is a bug. They display fine and I can add items, however an exception is thrown when I try to remove an item. At first I thought it may be something in my code, however I see the same error in the Examples_CSharp scene on the AIExample7_Collection. Basically trying to remove an item from any of the lists throws the following exception:

     
  20. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    That's very very very odd... It's not an exception, only a Debug.LogError. However, it's not from my code.
    It occurs when the Inspector is trying to save the state of an object on the undo stack. Why would Unity add a LogError there?

    However, while the action's name is recorded properly, the state of the object isn't... and Unity is spitting a Debug.LogError.

    Honestly, I just have no idea what to do with that.
     
  21. barrenjunk

    barrenjunk

    Joined:
    Jul 10, 2013
    Posts:
    6
    Thanks for the reply. Not sure if this will help, but I initially ran into the issue when working with a ScriptableObject. On a MonoBehaviour the error shows but it still performs the remove / reorder operation. However on a ScriptableObject the error breaks the inspector. I ended up moving the component I was working on into a MonoBehaviour however it really is not the right place for it (its basically a data object used to store shader swapping information). I was able to reproduce the error by simply having an array of strings on a ScriptableObject... you can add elements but removing or reordering throws the exception. I can post the SO exception if you think it would help. Oh, I also updated to the latest point release (5.1.0p1) and its still an issue. Interestingly enough, a coworker who updated to 5.1 but did not update AdvancedInspecter has that weird color issue but does not get the above LogError when working with collections on a MonoBehaviour. These types of issues are a pain to track down, hopefully that helps.
     
  22. BehemothPro

    BehemothPro

    Joined:
    Feb 14, 2015
    Posts:
    19
    Hey, I'm using v1.55 and the following code gives a NullReferenceException. This is based on one of the examples. On Lines 10 and 16 I added [AdvancedInspector]. And on lines 22,23 I added a UnityEvent which seems to be the problem. AI gives an error when trying to draw UnityEvents in an array of a class.

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Text;
    5.  
    6. using UnityEngine;
    7. using UnityEngine.Events;
    8. using AdvancedInspector;
    9.  
    10. [AdvancedInspector]
    11. public class AIExample38_Constructor : MonoBehaviour
    12. {
    13.     // In some case, you may want a class to have a custom constructor.
    14.     // Usually, Unity is unable to invoke that constructor.
    15.     [Serializable]
    16.     [AdvancedInspector]
    17.     public class CustomConstructor
    18.     {
    19.         [Inspect]
    20.         public string value;
    21.  
    22.         [Inspect]
    23.         public UnityEvent unityEvent;
    24.  
    25.         public CustomConstructor(string text)
    26.         {
    27.             value = text;
    28.         }
    29.     }
    30.  
    31.     // Advanced Inspector allows you to create your own instance using the constructor attribute.
    32.     // You may setup your object as you wish before returning it.
    33.     [Inspect, Constructor("InvokeConstructor")]
    34.     public CustomConstructor[] constructors;
    35.  
    36.     public CustomConstructor InvokeConstructor()
    37.     {
    38.         return new CustomConstructor("This was added in a constructor");
    39.     }
    40. }
    41.  
     
  23. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    You should try

    Code (CSharp):
    1. public UnityEvent unityEvent = new UnityEvent();
    I know Unity tends to initialize all object on serialization, but it's usually a very bad practice from not initializing your field.
     
  24. BehemothPro

    BehemothPro

    Joined:
    Feb 14, 2015
    Posts:
    19
    Ah ok. It still gives the same error.

     
  25. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Yikes... Just found out why. For now, it's not possible to have Property Drawer working inside a nested object inside a collection. Sorry about that, I'll fix it for the next version.
     
  26. BehemothPro

    BehemothPro

    Joined:
    Feb 14, 2015
    Posts:
    19
    Nice. Thanks!
     
  27. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Contact me at admin@lightstrikersoftware.com if it's blocking you, I'll send you a beta version of the fix.
     
  28. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    Hey,

    If I want to have a PropertyDrawer for a particular class handle being in a UDictionary how would I write it to handle that? I overwrote the default SpriteEditor with a property drawer because Unity's leaks like a sieve. But it only handle raw fields of Sprite not the UDictionary type. It gives me unsupported type errors because the dictionary itself isnt based on Object.
     
  29. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I'm not completely sure what you mean.

    However, one thing is sure, PropertyDrawer that are using SerializedObject or SerializedProperty will never work with some of the feature of the Advanced Inspector, such as property inspection or dictionary.

    If you have access to the code of that PropertyDrawer, I would advice to rewrite it into a FieldEditor, which doesn't have the limitation a PropertyDrawer has.

    You can contact me at admin@lightstrikersoftware.com and I'll be happy to help you find a solution to your issue.
     
  30. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    61
    Just bought Advanced Inspector and I have to say its excellent!
    I have just one question, is it possible to have in a collection the content of a custom field instead of the index?
    For example I have a List of custom objects like this:
    [Serializable]
    class Test {
    public string Name;
    public int Val;
    }
    Now I would like to have the content of the name field displayed instead of [0] [1] etc. - kinda like the "feature" of Unity when you have a public string field as the first field in a serializable class and use that in a list, the custom inspector will show the string field value instead of "Element 0".
     
  31. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Nope, you cannot replace directly an index displayed, but you can bind it to an enum. However, there's something as good - if not better; if you override the "ToString" method, it shows up like this;

    Code (CSharp):
    1. public override string ToString() { return name; }


    The idea here is that everything on the left of the separator is strongly bonded to the data. This allows for right-clicking the labels and having ton of new features like copy/paste.
     
    Froghuto likes this.
  32. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    61
    This is perfect, thanks for the fast answer!
     
  33. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    61
    I think I might have found a bug. I have a list containing some [Serializable] class, when I right click -> Copy and Paste on the list elements the values of the fields of the elements get copied, when I shift click + drag one element onto another it seems the class instance gets set to the new element, if I change some value in the copied element it also gets changed in the source element. I hope it is clear what I mean :)

    Edit: One more thing, I have a field in the [Serializable] class that contains a reference to a "ScriptableObject" Asset reference (residing in the Project, not the Scene). When I Copy/Paste a list element, in the pasted element the reference no longer points t the asset but to a copy of that asset. When I click it it does not highlight anything in the Project EditorWindow so it seems to be a copy in memory or something like that.
     
    Last edited: Jul 3, 2015
  34. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    I have nothing but a List<int> being inspected and trying to remove or move an item is causing this (Unity 5.1.1p2):

    NullReferenceException: Object reference not set to an instance of an object
    AdvancedInspector.InspectorField.RecordObjects (System.String text) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorField.cs:2172)
    AdvancedInspector.AdvancedInspectorControl.RemoveItem (AdvancedInspector.InspectorField field, Int32 index) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:2990)
    AdvancedInspector.AdvancedInspectorControl.DrawIndexedControl (AdvancedInspector.InspectorField field) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1624)
    AdvancedInspector.AdvancedInspectorControl.DrawNode (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField field, Boolean refresh, Boolean expansion) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1211)
    AdvancedInspector.AdvancedInspectorControl.Draw (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField parent, System.Collections.Generic.List`1 fields, Boolean newGroup, Boolean refresh, Boolean expansion) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:774)
    AdvancedInspector.AdvancedInspectorControl.DrawChildren (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField field, Boolean refresh, Boolean expansion) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1516)
    AdvancedInspector.AdvancedInspectorControl.DrawNode (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField field, Boolean refresh, Boolean expansion) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1244)
    AdvancedInspector.AdvancedInspectorControl.Draw (AdvancedInspector.InspectorEditor editor, AdvancedInspector.InspectorField parent, System.Collections.Generic.List`1 fields, Boolean newGroup, Boolean refresh, Boolean expansion) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:774)
    AdvancedInspector.AdvancedInspectorControl.Inspect (AdvancedInspector.InspectorEditor editor, System.Collections.Generic.List`1 fields, Boolean newGroup, Boolean refresh, Boolean expansion, .Separator externalSeparator) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:676)
    AdvancedInspector.AdvancedInspectorControl.Inspect (AdvancedInspector.InspectorEditor editor, System.Collections.Generic.List`1 fields, Boolean newGroup, Boolean refresh) (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:614)
    AdvancedInspector.InspectorEditor.DrawAdvancedInspector () (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:354)
    AdvancedInspector.InspectorEditor.OnInspectorGUI () (at c:/Users/LightStriker/Desktop/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:322)
    UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean forceDirty, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect, Boolean eyeDropperDirty) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1162)
    UnityEditor.DockArea:OnGUI()
     
  35. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Sorry for that, I had the brilliant idea of forgetting a Debug.LogError only in the Unity 5+ version, and I was wondering why I couldn't find this method in the 4.6 version. It shouldn't affect anything.
     
  36. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I'm investigating... Both should not happen - obviously.
     
    Froghuto likes this.
  37. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    It actually is an exception and it will not remove the item, nor let me move items in the list. If I try to move stuff in the list I get errors about mismatched mouse down or something.
     
  38. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Ah! Contact me at admin@lightstrikersoftware.com, I'll send you a fixed version.
     
  39. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Version 1.57 have been submitted to the asset store with the following changes;
    • Fixed an issue of AnimationCurve not being initialized on creation.
    • Fixed an issue where Property Drawer - such as UnityEvent - would fail to draw when nested in a collection.
    • Fixed an exception thrown when a base class has no valid derivation while using CreateDerived.
    • Found and removed a left-over Debug.LogError in the 5.1 version.
    • Fixed an issue where none-Unity object value would not be copied properly when dragged and dropped.

    And just taking a few second to explain where this package is heading from now. There will maybe be a version 1.58 if some critical issues are found, however I plan to jump to 1.60; a major revision. Last major revision showed lot of new features like the Save and Watch. However, not this one. Instead of new features, it will be some major refactoring.

    One thing I came to hate over time is how the tool has hard references to the attributes. Which means, it's general hard to write new attributes for it, since it means potentially writing new Field Editor to react to that attribute. It also means my code is mined with assumption that the attributes exist and are working in a specific way. In 1.60, I plan to remove all dependencies towards attributes and reroute them to interfaces.

    It sounds complicated, but in short, it means you could do something like this;

    Code (CSharp):
    1. public class VisibleIfPlaying : Attribute, IVisible
    2. {
    3.     public bool IsVisible()
    4.     {
    5.         return Application.isPlaying;
    6.     }
    7. }
    8.  
    9. [VisibleIfPlaying]
    10. public float myDebugField;
    11.  
    So all the Advanced Inspector internal mechanism would all be exposed by interfaces, which means you could write the attributes of your choice that would drive them. And since they would be interfaces, you could also combine them.

    Now, I keep working on 3 solutions at the same time, which is burning me a lot of time I could spend actually making features. Right now, there's a 4.3, 4.6 and 5.1 versions (and a deprecated 5.0 on the store). Hopefully 1.57 (or 1.58) will be stable enough that I could focus on 5.1+ from now on. From what I understand, PlayStation and Xbox builds are no longer stuck at 4.3, and now have a 5+ version for them. There's still a lot of people using 4.6, but the number just keep decreasing.

    So the plan is to keep potential stability build on 4.3/4.6, but new features only for 5.1+.
     
    Last edited: Jul 5, 2015
    electroflame likes this.
  40. nickpettit

    nickpettit

    Joined:
    Dec 31, 2013
    Posts:
    33
    O...M...G...

    I was pulling my hair out for 3 days trying to figure out these NullRefs! I was doing simple stuff and thought I just didn't understand Unity serialization well enough or something. So happy to find this post!
     
  41. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    1.57 is now available on the store.
     
  42. Froghuto

    Froghuto

    Joined:
    Oct 4, 2012
    Posts:
    61
    I updated to 1.57, just wanted to let you know, the bug with the shift-drag+drop copy is fixed, but the "ScriptableObject" fields bug is still there (the referenced ScriptableObject get "copied" instead of only copying their reference).
     
  43. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Damn... I knew I was forgetting something.
     
  44. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Contact me at admin@lightstrikersotfware.com, I got a fixed version if you want it right away.
     
  45. Ghopper21

    Ghopper21

    Joined:
    Aug 24, 2012
    Posts:
    170
    Hi there - basic question about Advanced Inspector. Is it an alternative to Full Inspector or something that you'd use together with Full Inspector? Thanks.
     
  46. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    They both can be used at the same time. The strength of Full Inspector is that it offers a different serialization, while Advanced Inspector offers a ton of tool to display data without having to write editors.
     
  47. OnAndOn

    OnAndOn

    Joined:
    Feb 14, 2015
    Posts:
    11
    Hi,
    I just bought AI yesterday and have a basic question, when using it with public properties with private backing field.

    For the slightly modified AIExample2_Inspect.cs in C# examples folder:

    Code (CSharp):
    1.  
    2. [AdvancedInspector]
    3. public class AIExample2_Inspect : MonoBehaviour
    4. {
    5.     // The Inspector attribute is used to display something by the Advanced Inspector.
    6.     // By default, everything is hidden.
    7.     //[Inspect]
    8.     //public string myField;
    9.       private string myField; //Changed to private.
    10.     // Properties can also be inspected.
    11.     [Inspect]
    12.     public string MyProperty
    13.     {
    14.         get { return myField; }
    15.         set { myField = value; }
    16.     }
    If backing field is made private then this doesn't work somehow. The property is displayed and can be changed in edit mode, but as soon as play mode is started the value reverts to null.
    Do I need to write custom editor to support public properties with private backing fields? Or am I missing something?

    I'm using v1.57 on Unity 5.1.2.
     
  48. KJoanette

    KJoanette

    Joined:
    Jun 8, 2013
    Posts:
    59
    Private fields are not serialized by default, and properties are not serialized at all. Mark your private field as SerializeField and it should be fine.
     
  49. OnAndOn

    OnAndOn

    Joined:
    Feb 14, 2015
    Posts:
    11
    @KJoanette Thank you! That solved my problem.
     
  50. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Someone was faster than me on this. ;)