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
    The easy way to have a MonoBehaviour not affected by AI is simply to have a custom editor, even if this custom editor is empty and do nothing.

    Code (CSharp):
    1.     [CustomEditor(typeof(MyType))]
    2.     public class MyTypeEditor : Editor
    3.     { }
    I've been thinking for a while to have an attribute you can place on a class to make AI ignore it, but didn't have time to do it yet.
     
  2. Waz

    Waz

    Joined:
    May 1, 2010
    Posts:
    287
    This pattern of referencing child objects in prefabs is used throughout my project, so I'd really rather AI not destroy these prefabs if I look at them. Is there a workaround (other than changing all my code)?
     
  3. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    That specific bug is not about referencing child nodes. It's specifically when applying a specific field manually that reference another node in the scene.
     
  4. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    No. It's about referencing child nodes in the prefab and how AI fails to handle this correctly because it doesn't serialize the references right and corrupts the results.

    This is not about manual anything... I made like 4 videos to try to explain this problem.

    It has nothing to do with multiple scenes.. it is very simple...

    Reference child node. Save as prefab. Press broken "apply" button in AI... now AI has failed. Prefab is corrupt.
     
  5. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    Step 1: Make game object ("A")
    Step 2: Add monobehaviour with a field that is a reference.
    Step 3: Add a child game object ("B"). Set the field in "A" -> "B"
    Step 4: Save as prefab

    Advanced Inspector's display is now incorrect (shows a modification in the prefab immediately after creating it).

    Right click "Apply to Prefab" will now write bad data to the prefab, corrupting it (it will try to write the scene instance of B to the prefab - which is not allowed and incorrect).


    ^^ This has nothing to do with multiple scenes or manual anything.. this is very basic problem with referencing child nodes. AI doesn't understand how prefabs work because it's author doesn't understand how prefab references work.

    @LightStriker can I have a refund now, since it's clear you will not fix this problem correctly?
     
  6. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Your steps are exactly what I just said.

    You manually do "Apply" to a specific field on a reference to a child node from an instance of a prefab in a scene.

    Prefab is not corrupted, because the moment you close your scene or restart unity, the Prefab field references Null.

    It is an issue I'm working on, but not an easy one, and not one that can be fixed in some cases (ex.: Proprieties).
     
  7. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    4,044
    The problem begins when you create the prefab (AI shows the field as having change immediately). The corruption of data happens when you use AI to apply changes.

    The prefab is corrupt because it doesn't save the correct reference. Having it revert to null is a major bug, the value should not be null, it should reference the relative path in prefab not scene reference.

    I am very frustrated with this - I spent hours making a bug report including video to make it as clear as possible. Your responses still don't seem to acknowledge the problem correctly. That you claim the prefab isn't corrupt when AI is saving wildly incorrect values is ridiculous.
     
  8. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Now that 2017.1 is the official current version, will there be an update to Advanced Inspector to fix the API mismatch issues?

    To be honest, I was very impressed with AI, and grateful to Lightstriker for working with me directly on the issues I was having. Waiting for updates to bring this up to snuff with 2017.1.

    This message has been modified to more accurately reflect my views. My post previously represented the asset in a more unfavorable light than is fair.
     
    Last edited: Aug 4, 2017
  9. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I just submitted a version with fixes for 2017.1
    Was surprised that Unity decided to change the Texture2D.Load method, which is quite low level.

    However, because of that issue, Advanced Inspector is now split into two version that cannot work with each other;
    • 5.2 to 5.6
    • 2017+
    Be sure to have the right version.

    What do you mean your prefabs losing values? Can you give me an example of that issue?
     
    Schneider21 likes this.
  10. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    3,512
    Awesome! Looking forward to it!

    I had a ridiculously complicated system for managing custom event data, with custom classes nested inside dictionaries inside classes all in one big dictionary... So I'm not positive it wasn't my fault, mind you. But sometimes the data seemed to serialize just fine, and other times (if I recall correctly, during the times when Unity would randomly scale my Gameplay window to 2x (known issue on Mac), the contents would be lost or a prefab reference would look like it was still in place, but trying to access it would throw a null ref.

    I've actually since then totally rewritten my game to not use this event system (twice, in fact), and I suppose the real reason I'm not currently using AI is because I'm on 2017.1. Guess I shouldn't have typed my previous message before recalling the events correctly. o_O
     
  11. LightStriker

    LightStriker

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

    ok. o_O
     
  12. cloudcamaleoniv

    cloudcamaleoniv

    Joined:
    May 17, 2013
    Posts:
    57
    Hello. I needed to create a TimeSpan AttributeDrawer to explicit this field to our Designer, but I was sick of creating LOTS AND LOTS of AttributeDrawers and Custom Inspector, so I bought your package.

    It seems to be a very good custom inspector, but I think I'm missing something here.

    When I have a public TimeSpan or a DateTime in my ScriptableObject, your plugin renders them beautifully in the Inspector Window, BUT when I hit Play in the Editor, the values reset back to its default values.

    Am I missing something? Do they need some Attribute?

    EDIT: I use Unity 5.6.2f1
    EDIT: I'm reading the manual. It seems that some fields are just rendered at the inspector by the plugin, but not serialized. It seems to be the case for TimeSpan and TimeDate. If this is true, is it possible to serialize them using your plugin? Is there some shortcut? Or best practice? Or will I need to create my own ISerializationCallbackReceiver implementation?
     
    Last edited: Aug 11, 2017
  13. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Hey

    Your edit is right, Unity does not serialize TimeSpan nor TimeDate. However, serializing them once you can expose properties to the Inspector is a piece of cake!

    Example:

    Code (CSharp):
    1.         [SerializeField, HideInInspector]
    2.         private long time = 0;
    3.  
    4.         [Inspect]
    5.         public TimeSpan Time
    6.         {
    7.             get { return new TimeSpan(time); }
    8.             set { time = value.Ticks; }
    9.         }
    Here I save it as a long, but TimeSpan can also be saved as a string using ToString()/Parse(). Or you can save a couple of Ints too. Up to you.

    The idea of AI is to uncouple serialization from the inspector. Often, what you save is not readable, and what you expose might have little to do on how you save it. :)
     
  14. cloudcamaleoniv

    cloudcamaleoniv

    Joined:
    May 17, 2013
    Posts:
    57
    Holy sh*t, properties can be inspected too. Okay, I'm giving 5 stars to this plugin. Thanks for the fast answer man.
     
  15. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    There's not much that cannot be inspected. When you have some free time, take a peek in the manual. :)
     
  16. xalsVR

    xalsVR

    Joined:
    Jan 2, 2014
    Posts:
    16
    Hi!
    Any way to use a [Angle] attribute with custom/clamped ranges?
    Maybe something like [Angle(0,50)] to clamp between 0 and 50... an so.

    Thanks!
     
  17. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Have your tried

    Code (CSharp):
    1.         [Angle, RangeValue(0, 360)]
    2.         public float wheel;
     
  18. xalsVR

    xalsVR

    Joined:
    Jan 2, 2014
    Posts:
    16
    Works like a charm! Thanks!
     
  19. Lecht

    Lecht

    Joined:
    Jul 1, 2014
    Posts:
    24
    I keep getting an exception when viewing anything with a color property:
    Trying to draw a Property Drawer of type ColorPropertyDrawer without a proper serialized property. This usually happen, while exposing a property-drawer driven value from a property or a dictionary.
    UnityEngine.Debug:LogError(Object)
    AdvancedInspector.AdvancedInspectorControl:DrawField(InspectorEditor, InspectorField, PropertyDrawer[], Dictionary`2, FieldEditor, GUIStyle) (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1256)
    AdvancedInspector.AdvancedInspectorControl:DrawNode(InspectorEditor, InspectorField, Boolean, Boolean) (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:1159)
    AdvancedInspector.AdvancedInspectorControl:Draw(InspectorEditor, InspectorField, List`1, Boolean, Boolean, Boolean) (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:799)
    AdvancedInspector.AdvancedInspectorControl:Inspect(InspectorEditor, List`1, Boolean, Boolean, Boolean, Separator) (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:702)
    AdvancedInspector.AdvancedInspectorControl:Inspect(InspectorEditor, List`1, Boolean, Boolean) (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/AdvancedInspectorControl.cs:641)
    AdvancedInspector.InspectorEditor:DrawAdvancedInspector() (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:496)
    AdvancedInspector.InspectorEditor:OnInspectorGUI() (at A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 5/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:385)
    UnityEditor.DockArea:OnGUI()
     
  20. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Well, the error message is kinda clear; you're trying to draw a PropertyDrawer from a Property or a type that Unity doesn't handle directly as serialization.

    Can you post the part of your code you're exposing that has this issue? "ColorPropertyDrawer" sounds like something possibly custom...
     
  21. Wild-Factor

    Wild-Factor

    Joined:
    Oct 11, 2010
    Posts:
    607
    On the new version of Unity I've got this error
    2017.1.0p2 and last beta of Unity

    Eachn time the inspector refresh:
    Code (CSharp):
    1.  
    2. [Exception] ReflectionTypeLoadException: The classes in the module cannot be loaded.
    3. Assembly.GetTypes()    /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/Assembly.cs:371
    4.  
    5. AdvancedInspector.FieldEditor.Gather()    A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 2017/Lib/AdvancedInspector/AdvancedInspector/FieldEditor.cs:142
    6.  
    7. AdvancedInspector.InspectorEditor.OnEnable()    A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 2017/Lib/AdvancedInspector/AdvancedInspector/InspectorEditor.cs:184
    8.  
    9. AdvancedInspector.BehaviourEditor.OnEnable()    A:/LightStrikerSoftware/Projet/AdvancedInspector/AdvancedInspector 2017/Lib/AdvancedInspector/AdvancedInspector/InspectorEditors/BehaviourEditor.cs:57
    10.  
    11.  
    And of course advanced inspector doesn't work anymore.

    I didn't get this error previously. I've reimported all.
    A solution.

    Thanks.
     
  22. Wild-Factor

    Wild-Factor

    Joined:
    Oct 11, 2010
    Posts:
    607
    Fix alone.
    It was FX quest. I update it, and it work now.
     
  23. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Love when I have nothing to do to fix something. ^.^
     
  24. PassivePicasso

    PassivePicasso

    Joined:
    Sep 17, 2012
    Posts:
    100
    Is there anyway to make use a string on a value of an element in an array be used as the label?
    Take this for example;
    upload_2017-9-22_21-32-54.png
    I'd like the replace "Float Ranges[x]" on the left, with the text on the right.
    I've been trying to figure out a way to do it, and I've looked over the documentation and can't seem to find anything on the subject.

    This array is of this type;
    public class FloatMap { string Key; FloatRange Value; }

    And declared as

    [Inspect, Collection(Size = 0, Sortable = false)]
    public FloatMap[] FloatRanges;

    I'm using a FieldEditor at the moment to change the rendering
     
  25. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Sure. If you look at the AIExample7_Collection, you can see a Collection attribute that has a Method name pass to it.

    Code (CSharp):
    1.         private string[] GetItemNames()
    2.         {
    3.             return items;
    4.         }
    It returns the a string for each element to be used as labels.
     
    PassivePicasso likes this.
  26. PassivePicasso

    PassivePicasso

    Joined:
    Sep 17, 2012
    Posts:
    100
    Excellent! Thanks for the tip now I have everything working how I want it!
    upload_2017-9-22_22-46-29.png
     
  27. LunaTrap

    LunaTrap

    Joined:
    Apr 10, 2015
    Posts:
    120
    Hi! I would like to be able to retrieve the current enum state or a way of knowing which tab is being shown currently of a tab, how can I do this?
     
  28. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Can you give me an example of what you would use that for?
     
  29. LunaTrap

    LunaTrap

    Joined:
    Apr 10, 2015
    Posts:
    120
    I'm writing a script to store profiles for the particle system variables, and when one profile is selected to update the particle system script to reflect that profile.

    More specifically to have quality profiles for particles. so I want to show how a particle looks when quality is selected.
     
  30. LunaTrap

    LunaTrap

    Joined:
    Apr 10, 2015
    Posts:
    120
    I can just use a standard enum field, but I want to know If I can use a tab for a better look.
     
  31. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Right now, tabs are only visual sorting of existing items. It has none of the hook required to actually modify data.

    Sorry, right now I think a dropdown list might be your best bet. I'll think about it a bit more.
     
  32. LunaTrap

    LunaTrap

    Joined:
    Apr 10, 2015
    Posts:
    120
    Ok, thanks
     
  33. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    If you use Advanced Inspector on a project in 2017.1.2 with .NET 4.6 (change it in player settings) .
    You get this warning if you move an transform with a advanced inspector script on it:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using AdvancedInspector;
    4. using UnityEngine;
    5.  
    6. [AdvancedInspector(true,false)]
    7. public class hfhfdhgd : MonoBehaviour {
    8.     [ReadOnly][Inspect] int test;
    9.  
    10.     // Use this for initialization
    11.     void Start () {
    12.      
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update () {
    17.      
    18.     }
    19. }
    20.  
    upload_2017-10-31_12-32-0.png

    As you can see the Transform inputs are not correctly aligned.

    Can you fix it ?
     
  34. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    The issue is only with .NET 4.6?? I'll fix it... even if I have no clue right now what might be causing it.

    You had no other warning or error poping? Just that layout warning?
     
  35. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    The problem appear only with .NET 4.6.
    That's all I'll have, no other warning or error. That kind of error is throw when EditorGUILayout.BeginHorizontal() is called without EditorGUILayout.EndHorizontal() I've read, but it must be something more tricky because the problem only appear in .NET 4.6.
    Tell me if you can reproduce the error.
     
  36. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    That is so damn weird... As if .NET 4.6 compiled differently, or some instruction we not handled properly.
     
  37. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    I have another issue (easier to fix I think).
    I'm trying to use this: https://github.com/redbluegames/unity-notnullattribute
    It has as useful NotNull attribute that throw an error if a serialized field having this attribute is no assigned in inspector.

    But it seem to conflict with Advanced Inspector in some way. This plugin is quite small.

    This is the error, can you tell me how to fix it ? (probably something to modify in the notnull plugin)

     
  38. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Can you show me on what you applied it that throws the error?
     
  39. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    Code (CSharp):
    1.         [SerializeField, NotNull] private Transform realMap;
    2.  
    On a Transform, is that what you need ?
     
  40. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    Yeah, that's very odd. It should work just fine. Let me dig a bit.
     
  41. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    Damn, I have another issue. If you create a camera and attach a newly created render-texture to it you get this error spamming the console in editor mode:

    Assertion failed: Assertion failed on expression: 'tex->GetWidth() == width && tex->GetHeight() == height'
    UnityEngine.Camera:Render()
    AdvancedInspector.CameraEditor:DrawWindow(Int32) (at Assets/Plugins/Editor/AdvancedInspector/UnityTypes/CameraEditor.cs:194)
    UnityEngine.GUIUtility:processEvent(Int32, IntPtr)

    By the way, I think I never told you that I am using unity 2017.1.2, might be usefull to know.
     
  42. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    Hello.
    There are a lot of big Custom PropertyDrawers written in our company.
    Can I disable the Advanced Inspector for specific fields or classes?
     
  43. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    Extend prev question.

    I try re implement old PropertyDrawer to FieldEditor for Fix32

    Fix32 is struct for deterministic float. (https://github.com/theIedU/DPhysics/blob/master/Assets/FixedMath/Fix32.cs)
    /// Structure for fixed point calculations.
    /// The representation uses 64 bits to store the number, with a shift of 16 bits.
    /// The number is stored as 1 (sign) | 15 + 16 + 16 = 47 (integer part) | 16 (decimal part)
    For unity editor I represent this as:
    one label with raw vaule (long)
    and float field


    Old
    Code (CSharp):
    1. namespace Unity.Editor
    2. {
    3.     [CustomPropertyDrawer(typeof(Fix32))]
    4.     public class Fix32Drawer : PropertyDrawer
    5.     {
    6.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    7.         {
    8.             var name = property.displayName;
    9.  
    10.             property.Next(true);
    11.             var rawValue = property.Copy();
    12.             var rawValueLong = rawValue.longValue;
    13.  
    14.             var f = new Fix32((long)rawValueLong);
    15.  
    16.             EditorGUI.BeginChangeCheck();
    17.  
    18.             var d = EditorGUI.FloatField(position, name, (float)f);
    19.  
    20.             if (EditorGUI.EndChangeCheck())
    21.             {
    22.                 rawValue.longValue = (new Fix32(d)).RawValue;
    23.             }
    24.             EditorGUILayout.LabelField(name + "_raw", rawValueLong.ToString());
    25.         }
    26.     }
    27. }
    new

    Code (CSharp):
    1. public class Fix32Editor : FieldEditor
    2. {
    3.     public override Type[] EditedTypes
    4.     {
    5.         get { return new Type[] { typeof(Fix32) }; }
    6.     }
    7.  
    8.     public override bool IsExpandable(InspectorField field)
    9.     {
    10.         return false;
    11.     }
    12.  
    13.     public override void Draw(InspectorField field, GUIStyle style)
    14.     {
    15.         object o = GetValue(field);
    16.         Type type = o.GetType();
    17.  
    18.         var f = (Fix32) o;
    19.  
    20.         EditorGUILayout.LabelField("raw", f.RawValue.ToString());
    21.  
    22.         EditorGUI.BeginChangeCheck();
    23.         var d = EditorGUILayout.FloatField("float", (float) f);
    24.         if (EditorGUI.EndChangeCheck())
    25.         {
    26.             Debug.Log("set new raw");
    27.             f.SetRaw((new Fix32(d)).RawValue);
    28.         }
    29.     }
    30. }
    Its compiled without errors, but editor is only view values.
    Screenshot https://www.dropbox.com/s/un33c906q9xuxzf/Unity_2017-11-05_16-07-09.png?dl=0
    How make field float writable?
     
  44. AmbroiseRabier

    AmbroiseRabier

    Joined:
    Dec 4, 2016
    Posts:
    14
    I've tried few thing regarding my issues:
    - 4.6 NET break inspector layout. Workaround is to disable all Editors scripts in preferences.
    - Camera Editor, disable it in preferences/adv. inspector/editors (any .NET version)
    - NotNull attribute, comment OnGUI method (in NotNullAttributeDrawner.cs) (but you won't have warnings in inspector anymore, only in console), or disable Inspect Default Items and don't use AdvancedInspector attribute (in other words the OnGUI method is incompatible).
     
  45. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I have no idea why sometimes the forum just stop warning me about new posts.

    Can you contact me at admin@lightstrikersoftware.com? I would gladly help you sort it out.
     
  46. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    That usually happens when an exception have been thrown by your editor. Instead of breaking the whole inspector windows, it default back to read-only to prevent data corruption.

    Can you email me the Fix32 type? I will be glad to figure out what's happening.
     
  47. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    The 4.6 NET issue is really taking me a lot of time. So far I haven't tracked down anything meaningful, even if I have a good idea of where it is happening, I still have no clue as to why.
     
  48. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
  49. evreng

    evreng

    Joined:
    Oct 24, 2014
    Posts:
    4
    I would like to use your CreateDerived example in a scriptable object. But, because ccriptable object does not derive from monobehaviour, gameObject.AddComponent<AIExample_DerivedClassA>(); gives an error on gameObject (gameObject does not exist in the current context). How can I add derived class in a scriptable object?
     
  50. LightStriker

    LightStriker

    Joined:
    Aug 3, 2013
    Posts:
    2,717
    I answered to you on Discord. ScriptableComponent exists, even if not a fully "supported" feature.