Search Unity

Full Inspector: Inspector and serialization for structs, dicts, generics, interfaces

Discussion in 'Assets and Asset Store' started by sient, Jan 23, 2014.

  1. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    I think you should submit a request to Unity that the API is still useful.
     
  2. Duffer123

    Duffer123

    Joined:
    May 24, 2015
    Posts:
    1,216
    @sient,

    Where's the link to the description of the [] attributes in the API? (like [InspectorHeader] and so forth?
     
  3. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    I have no idea where I would submit such a quest :O
     
  4. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    It should be here - is there something missing / broken?
     
  5. Duffer123

    Duffer123

    Joined:
    May 24, 2015
    Posts:
    1,216
    No - found it!
     
  6. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
  7. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    I posted about the issue in 5.2 Beta forum, may be that'll help.
     
  8. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    @sient - Just a head's up... Unity 5.1 has also added support for a Preserve attribute. You should add it to prevent stripping. It can be your own attribute, the only requirement is that it start with "Preserve" so you can add this:

    Code (csharp):
    1.  
    2. public class PreserveFullInspectorAttribute : Attribute
    3. {
    4.  
    5. }
    6.  
    Then on your constructor:

    Code (csharp):
    1.  
    2. public class FullSerializer
    3. {
    4.      [PreserveFullInspector]
    5.      public FullSerializer()
    6.     {
    7.        //...
    8.     }
    9. }
    10.  
    You could add it to any full inspector specific stuff you are having stripping issues with.
     
  9. sanpats

    sanpats

    Joined:
    Aug 24, 2011
    Posts:
    343
    I change that code to what appears below. If that bug you mentioned still exist should it throws some error immediately or will it occur only in certain condition? So far I haven't got any error.
    Code (CSharp):
    1. #if !UNITY_5_2
    2. if (fiLateBindings.EditorApplication.isPlaying && Application.isLoadingLevel) {
    3.     return;
    4. }
    5. #endif
     
  10. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    Hmmm... I found another FullInspector restriction...

    i have an interface:
    Code (csharp):
    1. public interface IData { }
    and a public field for specifying a type in a base behavior:
    Code (csharp):
    1. public FullInspector.TypeSpecifier<IData> MyDataType;
    So in the inspector will appear a drop down with every class implementing IData.
    But what I would need is another interface which derives from IData:
    Code (csharp):
    1. public interface IMyInterface : IData { }
    unfortunately that interface doesn't appear in the drop down list. The framework I built on top of FullInspector is very generic and I would really need this functionality (not in the framework but in the game which uses it).
     
    Last edited: Jul 30, 2015
  11. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Awesome, thank you for the heads up!
     
    Dustin-Horne likes this.
  12. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    I don't think you'll get any errors, you should be fine. The bug will emit some error/warning messages. I never actually was able to duplicate it.
     
  13. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Ah, this is because there is some shared code being used with the virtual/abstract type selection dropdown which requires the derived type be constructable. I'll get this fixed and send you a build. Thanks!
     
  14. dippnsk

    dippnsk

    Joined:
    Feb 12, 2015
    Posts:
    8
    Hi!

    Is it possible to have something like DefaultBehaviorEditor<T> but for tkControls? I see tkCustomBehaviorEditor<T>, but to use it, I need to draw every member of class via tk.PropertyField, before I go to real customization.
    I tried to use tk.DefaultInspector, but it fallbacks to recursive call of my custom editor. I just want to use automatic layout for few additional fields which goes at the end, similarly to OnAfterEdit().
     
  15. dippnsk

    dippnsk

    Joined:
    Feb 12, 2015
    Posts:
    8
    Please add extended documentation on Metadata with samples. I've spent 4 hours to rebuild my EditorGUILayout-based inspector to FullInspector architecture. The problem was in incorrect GetElementHeight calls, which requries metadata.Enter(<var_name>) as a last parameter for every field. This is not obvious at all.

    Also found few inconsistencies in logic:
    1. TypeSpecifier must acknowledge InspectorDropdownName attribute.
    2. Facade<T> for some reason won't show extended content from OnAfterEdit() calls.

    Overall - amazing asset, will buy in a few days, now using trial.
     
  16. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    I investigated this problem a little bit further. It seems as if Type.MakeGenericType() does not work as documented (maybe only in Unity-Mono).
    An argument exception should be thrown if:
    This does not happen (no exception is thrown).

    I added a little bit of code to fiReflectionUtility:
    Code (CSharp):
    1.         static Type MakeGenericType(Type openGenericType, params Type[] orderedTypeParams)
    2.         {
    3.             Type[] args = openGenericType.GetGenericArguments();
    4.  
    5.             if (args.Length != orderedTypeParams.Length)
    6.                 throw new ArgumentException();
    7.  
    8.             for (int i = 0; i < args.Length; i++)
    9.             {
    10.                 foreach(Type t in IterateGenericConstaints(args[i]))
    11.                 {
    12.                     if(t.IsAssignableFrom(orderedTypeParams[i]) == false)
    13.                     {
    14.                         throw new ArgumentException();
    15.                     }
    16.                 }
    17.             }
    18.  
    19.             return openGenericType.MakeGenericType(orderedTypeParams);
    20.         }
    21.  
    22.         static IEnumerable<Type> IterateGenericConstaints(Type genericParameter)
    23.         {
    24.             yield return genericParameter.BaseType;
    25.  
    26.             foreach (var iface in genericParameter.GetInterfaces())
    27.             {
    28.                 yield return iface;
    29.             }
    30.         }
    31.  
    And replaced line 227 in the same class (hope the line number is correct...):
    Code (csharp):
    1. Type createdType = MakeGenericType(openGenericType, orderedTypeParams);
    Now the drop down only shows class implementations which satisfy the constraints of the generic parameters.

    However I realized that I sometimes also want to trick the constraints (having ValueProvider<object> which should be able to have any value provider assigned to).
    Maybe you can bring my approach to the next level and divide the drop down: upper entries fit the constraints, lower entries (below a separation line or in a sub menu) don't...
     
  17. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi sient,

    With the latest (2.6.2a) version, I'm still getting the extra json output when serializing a BaseScriptableObject to .json, as in this issue here. Does the latest version of Full Inspector include the fix in Full Serializer, or do I need to download Full Serializer separately?
     
  18. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    I found another odd behaviour of full inspector...

    I have the following data types:

    Code (csharp):
    1.  
    2. public interface IMyInterface { }
    3.  
    4. public class MyComponent : UnityEngine.MonoBehaviour, IMyInterface { }
    5.  
    6. public class Test : FullInspector.BaseBehavior
    7. {
    8.   public IMyInterface MyVariable;
    9. }
    10.  
    When I add a the Test Script to a game object now and I select "MyComponent" from the MyVariable-DropDown, a "MyComponent" Script is added to the current game object. This is very annoying, because I normally want to point to another game object in the current hierachy instead, so I have to delete that again.

    And I have another problem which breaks my workflow completely. I am not sure what causes it... I think I didn't have this bug yesterday... The problem is the following:
    I cannot add any GameObject into the ObjectField. It reacts as if there where no MyComponent attached to the GameObject I'm dragging (but it is).
    I tried to make two inspector windows to drag the actual component into the ObjectField: also not possible. And the list of possible objects (when i click the littel o next to the ObjectField) is empty.

    however when I change the Test script to not use FullInspector everything works as expected.
    Code (csharp):
    1.  
    2. public class Test : UnityEngine.MonoBehaviour // <- no BaseBehavior anymore
    3. {
    4.   public MyComponent MyVariable; // <- no interface anymore (not possible with standard mono behaviour)
    5. }
    BTW: it also doesn't work if Test is a BaseBehavior and MyVariable has the type MyComponent (instead of IMyInterface).
     
  19. stevethorne

    stevethorne

    Joined:
    Apr 8, 2013
    Posts:
    16
    Hey sient,

    I love building my own dlls, but I just downloaded the latest from the asset store and the project files aren't there when I unzip the DLL bundle! Is there something I'm missing? There's no FullInspector-DLL-ProjFiles anywhere in there for me to unzip. I have a few changes I like to make before using it in my projects.
     
  20. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    I found the reason why I cannot drag my game object into the object field:
    in ObjectPropertyEditor.cs is a method "AllowSceneObjects()". this always returns false, cause it checks whether the object i am dragging is a subclass of ScriptableObject.
    I have no Idea what the purpose of this check should be... for me it doesn't make any sense...
     
  21. stevethorne

    stevethorne

    Joined:
    Apr 8, 2013
    Posts:
    16
    I'm also curious, how can I prevent stripping of FullInspector.FullSerializerSerializer when I'm using the DLLs and IL2CPP, I'd rather not use "new FullInspector.FullSerializerSerializer()" hack to do it.
     
  22. sz-Bit-Barons

    sz-Bit-Barons

    Joined:
    Nov 12, 2013
    Posts:
    150
    I tried the following: creating a link.xml file in the root Assets folder of the project and paste the following code:
    Code (csharp):
    1.  
    2. <linker>
    3.   <assembly fullname="FullInspector-Core">
    4.   <type fullname="FullInspector.FullSerializerSerializer" preserve="all"/>
    5.   </assembly>
    6. </linker>
    unfortunately I couldn't test it yet (no access to a mac right now). would be great if you could test it and share the result with me :)

    Edit: you probably have to change the assembly name to Assembly-CSharp if you don't use FI as DLL.
     
  23. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    What version of Unity are you using? As I posted previously you can create an attribute and as long as the name of the attribute starts with Preserve you can then apply it to classes, members and methods that you don't want to be stripped and the stripping engine will ignore it but I believe this is Unity 5.1 and above.
     
  24. metroidsnes

    metroidsnes

    Joined:
    Jan 5, 2014
    Posts:
    67
    Can I use Full Inspector to display lists of custom type in the EditorWindow?

    I couldn't find any info on that and the Samples scene attached to the 2.6.2 trial version does not work:



    I want to draw this list:

    Code (CSharp):
    1.  
    2. public class DefineSymbolsEditorWindow : ExtendedEditorWindow {
    3.  
    4.     // List to draw.
    5.     [SerializeField]
    6.     private List<TargetSymbols> targetSlots;
    7.  
    8. // ...
    9. }
    10.  
    11. [Serializable]
    12. public class TargetSymbols {
    13.  
    14.     public BuildTargetGroup BuildTarget;
    15.     public List<String> Symbols;
    16. }
    17.  
     
  25. brendan-vance

    brendan-vance

    Joined:
    Jan 16, 2014
    Posts:
    36
    We're experiencing an annoying problem in which many assets deriving from BaseScriptableObject flag themselves as 'Changed' in PlasticSCM even when we have made no modifications to them (so all of our commits look like we've changed 20 different files when in fact we've changed 0). Anyone seen anything like this before?
     
  26. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Does Plastic at least diff and undo the checkouts when it doesn't find any actual changes?
     
  27. brendan-vance

    brendan-vance

    Joined:
    Jan 16, 2014
    Posts:
    36
    It does! Although it does so simultaneously with commits, thus creating situations where the most convenient way to know whether you've modified a given asset is to commit and then look at the diff log.
     
  28. truffle_shuffle

    truffle_shuffle

    Joined:
    Dec 30, 2014
    Posts:
    16
    This is probably a really dumb question, but in the example below, how would I access items in the Effects List based on what is chosen from the drop down? I can't access the variables in the class that is chosen in the drop down. Something like this (assuming I chose "StatDecreaseEffect" from the drop down):
    Code (CSharp):
    1. foreach(BaseSkillEffect effect in Effects)
    2. {
    3.     Debug.Log(effect.Agility);
    4. }

    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. namespace FullInspector.Samples.DatabaseEditor {
    6.     public interface ISkillActivator {
    7.     }
    8.     public abstract class BaseSkillEffect {
    9.         public string Name;
    10.     }
    11.  
    12.     public class TimedActivator : ISkillActivator {
    13.         public float Delay;
    14.     }
    15.  
    16.     [Flags]
    17.     public enum EventMask {
    18.         EventA, EventB, EventC
    19.     }
    20.     public class EventActivator : ISkillActivator {
    21.         public EventMask EventFilter;
    22.     }
    23.  
    24.     public class DamagePlayerEffect : BaseSkillEffect {
    25.         public float Damage;
    26.     }
    27.     public class HealPlayerEffect : BaseSkillEffect {
    28.         public float RestoredHealth;
    29.     }
    30.     public class StatDecreaseEffect : BaseSkillEffect {
    31.         public float Armor;
    32.         public float Endurance;
    33.         public float Strength;
    34.         public float Agility;
    35.         public float Duration;
    36.         public List<float> Effects;
    37.     }
    38.  
    39.     public class Ability {
    40.         public string Name;
    41.         public int UnlockGoldCost;
    42.         public Texture Image;
    43.         [InspectorTextArea]
    44.         public string Description;
    45.  
    46.         public List<ISkillActivator> ActivationRequirements;
    47.         public List<BaseSkillEffect> Effects;
    48.     }
    49.  
    50.     [AddComponentMenu("Full Inspector Samples/Other/Database Behavior")]
    51.     public class DatabaseBehavior : BaseBehavior<FullSerializerSerializer> {
    52.         [InspectorComment(CommentType.Info, "If you have a huge collection of items, for example, a set " +
    53.             "of skills, then the [SingleItemListEditor] attribute can be extremely useful. It " +
    54.             "activates an editor that only shows you one item at a time.")]
    55.         [ShowInInspector]
    56.         [InspectorHidePrimary]
    57.         private int _comment;
    58.  
    59.         [InspectorDatabaseEditor]
    60.         public List<Ability> Abilities;
    61.     }
    62. }
     
  29. Wild-Factor

    Wild-Factor

    Joined:
    Oct 11, 2010
    Posts:
    607
    I'm only using full inspector trial.
    But I see major functions lost from the default inspector:
    - I can't multi-edit several BaseBehavior anymore. If I select several objects, and change one value, it doesn't work!
    - I can't replace monbehaviour by drag and drop (most drag & drop functions don't work anymore).
    If I have one class A. I create two new class inherit this class A let's call them B & C
    class A {..}
    class B: A {..}
    class C: A {..}

    If I have an component in the inspector with the script A, I can't replace it with B or C, without setting again all var by hand.
    (Before I just have to drag and drop file of class B, in the inspector, to replace the script, and get every var value transfert to the new class)

    Is it something we can fix ? configure ?
     
  30. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    @sient
    I am a new user of Full Inspector.
    Is there any comparing web page that lists out all/most types that BaseBehavior and MonoBehaviour supports differently? For example, the type list includes Dictionary, Transform ...
    Or, the type list is actually not long. Thus, it is not needed.

    A question about protocol buffer support.
    I saw that the documentation says that it is still in beta status. Is it ready to be used in production?
     
  31. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Unfortunately I don't think it's easily doable - I tried implementing it awhile back but was unable to find a good way to do so. Sorry!
     
  32. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    What were you doing instead of metadata.Enter?

    Fixed, PM me for a build if you want one.

    Would you mind giving me an example? OnAfterEdit should only be available for BehaviorEditors, and Facade can only be used with a PropertyEditor since it doesn't derive from UnityEngine.Object.
     
  33. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Would you mind sharing some code that actually breaks the generic constraints? I've implemented the split between types that do/do not violate the constraints and I would like to make sure I test it out.
     
  34. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    FI includes the latest version of FS, what extra JSON are you referring to? The FI data itself includes all of the metadata so things will deserialize properly.
     
  35. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Yes, this has been a tricky workflow because the abstract type dropdown editor needs an actual object instance to map the type. However, I just thought of a better workaround - Unity has this idea of an unattached MonoBehaviour instance, so we can use that instead of adding a component reference.

    Change line 100 of FullInspector2\Core\Utility\InspectedType.cs from

    Code (csharp):
    1. return activeGameObject.AddComponent(ReflectedType);
    to

    Code (csharp):
    1. return FormatterServices.GetSafeUninitializedObject(ReflectedType);
    Thanks, I have removed the SharedInstance check.
     
  36. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Can you send me a screenshot of what the root FI folder looks like? It should definitely be there in "FullInspector-DLL Builder.zip" I can also PM you the DLL files if you want.
     
  37. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Thanks sz and Dustin. Steve, did either of the two approaches work out for you?
     
  38. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    I wonder why the samples failed to decompress. Either way, they are also available here.

    Regarding embedding with an editor window, please see this section in the docs. Let me know if you still have questions. Thanks!
     
  39. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Sorry to hear about that. Have you figured out any specific steps that will cause an asset to get flagged? I'm guessing that only the timestamp changes on the file. Is there a way to make plastic ignore this?
     
  40. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    You need to do a type cast to access the data inside of the derived value. Note that the type cast may fail.

    I think the following should do the trick:

    Code (csharp):
    1.  
    2. foreach(BaseSkillEffect effect in Effects)
    3. {
    4.     if (effect is StatDecreaseEffect)
    5.       Debug.Log(((StatDecreaseEffect)effect).Agility);
    6.     else
    7.       Debug.Log("Not a stat decrease effect, instead it is a " + effect.GetType());
    8. }
    9.  
    Let me know. Thanks!
     
  41. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    The multi-editing is something that is currently not supported, though my plan is to get it done in 2.8. This depends on some rewriting in 2.7 that will make attribute editors much more powerful/flexible. Unfortunately I don't have a timeline for either of these updates yet.

    I haven't heard of the replacing script workflow, but I'm not sure it will be possible to implement. I just prototyped something and it ended up hard-crashing Unity. Beyond that, I'm not aware of a way to actually change the type of a MonoBehaviour without removing/readding it. This will cause the order of the item in the inspector to change.
     
  42. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    FI supports everything except for delegates, which I'll happily support if someone figures out how to serialize/deserialize them - I'm not sure of a way to do it that makes sense in the context of Unity. Is there a specific type you had in mind?

    I don't really recommend protobuf at this point, because there are a number of gotchas associated with the serializer itself (for example, it will deserialize empty collections as null iirc). Back when FI was first introduced, protobuf-net was faster than Unity's serializer, but that isn't the case anymore, so I don't think there is a good user-story for it.

    The AOT support will probably always be beta, simply because it relies on a decompiler.
     
  43. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi,

    I'm referring to this post and your reply in this post.

    In this issue here, at the bottom of the comments you mention this as fixed, but I'm still getting that extra output when serializing BaseScriptableObjects to JSON.
     
  44. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Ok, I'll take another look. Can you send me a specific example with code where this is happening? Thanks!
     
  45. Dan2013

    Dan2013

    Joined:
    May 24, 2013
    Posts:
    200
    Understood. Thanks.

     
  46. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi sient, sent you a pm with the info, thanks.
     
  47. sient

    sient

    Joined:
    Aug 9, 2013
    Posts:
    602
    Thanks, please see my reply.
     
  48. Korindian

    Korindian

    Joined:
    Jun 25, 2013
    Posts:
    584
    Hi sient, just reporting that the first solution you suggested in your pm did the trick, and the extra output is no longer there. It's also deserializing correctly. Thanks for the prompt support.

    Also, I was using the DLL version you included in the zip for faster compile times. The problem was that Unity was crashing after every compilation. When I would reload Unity, it would compile fine at start, but any change I made after that would crash Unity again.

    I then used the Asset Store version without the DLL, and the crashes went away, but I would get the error, "ReleaseAllScriptCaches not releasing all caches" as in the issue here. I also did Remove Metadata and did not get anymore errors. Just thought I'd mention it to you... I'm going to stick with the non-DLL version for now.
     
  49. brendan-vance

    brendan-vance

    Joined:
    Jan 16, 2014
    Posts:
    36
    Here is what Plastic has to say about the file it judges to be the 'previous revision' of an unchanged BaseScriptableObject subclass:

    Code (CSharp):
    1. Changeset: 367
    2. Size: 4.19 KB
    3. Created by: taylan.kay
    4. Date modified: 12/08/2015 11:45:46 AM
    And here is the 'updated' version:

    Code (CSharp):
    1. Changeset: 370
    2. Size: 4.19 KB
    3. Created by: bvance
    4. Date modified: 12/08/2015 1:58:02 PM
    It would appear that the asset is actually being rewritten (even changing the user account registered to be the file's creator). Is it possible the custom inspector stuff is rewriting every file it inspects regardless of whether we actually make changes to them?

    The ScriptableObjects in question contain a single generic List member, though I can discern no pattern as to why certain instances of them get flagged while others apparently do not. (For example, there are files created by taylan that do get flagged, and others that don't; there are similarly files created by me that do and don't get flagged as well. Some of the lists contain members while others are empty; I dunno.)
     
    Last edited: Aug 12, 2015
  50. Bhruood

    Bhruood

    Joined:
    Apr 27, 2013
    Posts:
    11
    Hello, I'm having problems when using FullInspector with properties that have a backing field, they simply will not show up in the editor window, for example:

    Code (CSharp):
    1. public class SomeClassName : BaseBehavior
    2. {
    3.     private float someValue = 12f;
    4.  
    5.     public float SomeValue
    6.     {
    7.         get
    8.         {
    9.             return someValue;
    10.         }
    11.         set
    12.         {
    13.             someValue = value;
    14.         }
    15.     }
    16. }
    Will not show up in the inspector, if I remove the backing field and make the property an auto-property everything works as expected, but auto-properties don't exactly provide the complete benefits of properties as you know.

    Any reason why this wouldn't be working, I'm using the latest version off the asset store if that matters.

    Thank you for your assistance.