Giter Site home page Giter Site logo

fullinspector's People

Contributors

hymerman avatar jacobdufault avatar sugoidev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fullinspector's Issues

Custom order of properties

Allow ordering of properties in the inspector so that partial classes can be customized w.r.t. field/property order

Multidimensional array support

Add inspector support for multidimensional arrays, such as char[,]. For the moment, char[][] can be used instead.

This issue replaces issues #14 and #15.

C# properties throwing Ref<> errors in 2.0

C# properties still throw Ref<> errors for non-BaseBehavior component types. For example, properties of type RigidBody or any custom MonoBehaviour still throw errors. Weirdly enough, Transform properties are ok.

So in this code, everything works fine except that SomeBehavior.body and SomeBehavior.normalBehavior cause the following errors to show in the console:

A property of type UnityEngine.Rigidbody needs to be wrapped in Ref<>
UnityEngine.Debug:LogError(Object)
A property of type NormalBehavior needs to be wrapped in Ref<>
UnityEngine.Debug:LogError(Object)

SomeBehavior.target and SomeBehavior.anotherBehavior don't cause any error.

Note that replacing C# properties with fields of the same type gets rid of any error. Note also that all four Debug.Log() successfully print out their injected instance, regardless of errors being thrown.

Here's the code:

public class NormalBehavior : MonoBehaviour
{
    public Vector3 someVector;
}

public class AnotherBehavior : BaseBehavior
{
    [SerializeField]
    [ShowInInspector]
    private int someInt { get; set; }

    [SerializeField]
    [ShowInInspector]
    private float someFloat { get; set; }
}
public class SomeBehavior : BaseBehavior
{
    [SerializeField]
    [ShowInInspector]
    private Transform target { get; set; }

    [SerializeField]
    [ShowInInspector]
    private Rigidbody body { get; set; }

    [SerializeField]
    [ShowInInspector]
    private NormalBehavior normalBehavior { get; set; }

    [SerializeField]
    [ShowInInspector]
    private AnotherBehavior anotherBehavior { get; set; }

    void Start()
    {
        Debug.Log(target);
        Debug.Log(body);
        Debug.Log(normalBehavior);
        Debug.Log(anotherBehavior);
    }
}

Another two small improvements about following Unity3D display rules

In the inspector view, format property names such that propertyName becomes "Property Name".

In the inspector view again, injected Object references should display the type of the property in parentheses. So if you drag and drop a gameobject named "SomeGameObject" into the Transform property of another game object, it should say "SomeGameObject (Transform)" in the label box of the property.

uint, long, ulong

It would be nice if FullInspector also exposed other integer data types to the inspector, rather than just (int).

Edit: They only seem to be hidden on ScriptableObjects. MonoBehaviours work, but they're capped.

Rename BaseBehavior to BaseBehaviour

This is just a minor request, if you don't agree just close this.

I often change a script which was originally a MonoBehaviour to a BaseBehavior by simply exchanging the word Mono to Base. The different notation lead to compile errors (type not found) a few times for me.

Migrate all non-api types to FullInspector.Internal

A number of types which should not be exposed to the public are available in namespace FullInspector. Changing their visibility to Internal does not do anything, as they are compiled into the same Assembly-CSharp DLL with all of the other code.

Add ScriptableObject Support

This will require a couple of changes:

  • Introduce a BaseScriptableObject. It looks like OnEnable might always be called, so that's one avenue for deserialization.
  • Ref<T> and ComponentConverter need to also support ScriptableObject

Prefab values not deserialized automatically

When accessing a prefab reference at runtime, I can check the values of unity-serialized fields. But since RestoreState hasn't been called for prefabs before they're instantiated, I can't access any FI handled fields.
At the moment I'm calling RestoreState manually on prefabs before accessing them, but would it be possible for this not to be necessary? (and is this workaround safe?)

2d char array Exception on Inspector

Building a 2d char array at runtime and then select the object after awake has been called.

Example Class:

using UnityEngine;
using FullInspector;
using Newtonsoft.Json;

[JsonObject(MemberSerialization.OptIn)]
public class CharTest : BaseBehavior
{
    public int sizeX;
    public int sizeY;
    public char[,] grid;

    protected override void Awake()
    {
        base.Awake();
        grid = new char[sizeX, sizeY];
    }
}

Exception Details:

InvalidCastException: Cannot cast from source type to destination type.
FullInspector.PropertyEditor`1[System.Char[]].FullInspector.IPropertyEditor.GetElementHeight (UnityEngine.GUIContent label, System.Object element) (at Assets/FullInspector/FullInspector/Editor/IPropertyEditor.cs:65)
FullInspector.PropertyEditors.ReflectedPropertyEditor.GetElementHeight (UnityEngine.GUIContent label, System.Object element) (at Assets/FullInspector/FullInspector/Editor/PropertyEditors/Special/ReflectedPropertyEditor.cs:223)
FullInspector.FullInspectorCommonSerializedObjectEditor.OnInspectorGUI () (at Assets/FullInspector/FullInspector/Editor/FullInspectorCommonSerializedObjectEditor.cs:63)
UnityEditor.DockArea:OnGUI()

How to save state to an created asset?

I have a BaseScriptableObject with a Dictionary-property:

[JsonObject(MemberSerialization.OptIn)]
public class MeshInfo : BaseScriptableObject
{   
        [JsonProperty]
        public Dictionary<string, bool>
                Properties;
}

I create an instance of if in an AssetPostprocessor and write it to a new .asset-file:

public class MyPostprocessor : AssetPostprocessor
{       
    void OnPostprocessGameObjectWithUserProperties (GameObject go, string[] propNames, System.Object[] values)
    {
        Dictionary<string, bool> properties = new Dictionary<string, bool> ();
        for (int i = 0; i < propNames.Length; i++) {
            if (values [i].GetType () == typeof(bool))
                properties.Add (propNames [i], (bool)values [i]);
        }
        MeshInfo meshInfo = ScriptableObject.CreateInstance<MeshInfo> ();
        meshInfo.Properties = properties;
        AssetDatabase.CreateAsset (meshInfo, assetPath + ".asset");
        AssetDatabase.SaveAssets ();
        meshInfo.SaveState ();
        FullInspector.FullInspectorSaveManager.SaveAll ();
    }
}

The file gets created and I see my bool dictionary in the inspector. But when I press play the content of the dictionary property is lost. So it is not serialized. When I manually add en entry to the dictionary in the inspector it is correctly written to disk.

As you can see I tried all Save-methods I can think of. Do you what is missing?

Thanks a lot! Btw. FullInspector is a really nice package!

Full Inspector should mimic Unity3D field display rules

Currently all fields will appear in the inspector window regardless of public, private, serialization flags, hide in inspector, etc. This is different than Unity's default, which is that only serialized fields will appear in the inspector window. While not a big deal, I can't even hide fields using the [HideInInspector] flag.

Feature request: Covariance and Contravariance support for interfaced properties

This is more feature request than an issue, feel free to close this if this is not the appropriate place for it.

The topic of covariance and contravariance is quite counter-intuitive so hopefully my example will make some sense. The "in" is really important. Say I have the following definitions.

[JsonObject(MemberSerialization.OptIn)]
public interface IAction<in T>
{
    void Act(T data);
}

[JsonObject(MemberSerialization.OptIn)]
public class DestroyGameObject : IAction<object>
{
    [JsonProperty]
    private GameObject gameObject;

    public void Act(object data)
    {
        // we ignore the data object in this case, just destroy the game object
        // but you can imagine a PrintMessage : IAction<string> action which prints
        // the given (at runtime) message
        GameObject.Destroy(gameObject);
    }
}

Given this, because T is contravariant in IAction, the following assignment is valid: (and that makes sense because DestroyGameObject.Act() should be able to accept a string parameter if it expects an object)

[JsonProperty]
IAction<string> action = new DestroyGameObject();

In other words, DestroyGameObject is a valid implementation of IAction, and so should appear in the dropdown list of concrete implementations of a IAction property in the inspector.

I imagine that making this work would only be a matter of doing more precise reflection by considering covariance and contravariance. More info on covariance and contravariance here:
http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx

SurrogateSelector does not disambigutate between types with the same name in different assemblies

Fixing this will require a custom implementation of ISurrogateSelector.

For reference, here is the Mono SurrogateSelector implementation from reflection:

// Type: System.Runtime.Serialization.SurrogateSelector
// Assembly: mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
// MVID: F7DE7BB6-83A9-4F92-BD7A-366EC18B3DE9
// Assembly location: C:\Program Files (x86)\Unity\Editor\Data\Mono\lib\mono\unity\mscorlib.dll

using System;
using System.Collections;
using System.Runtime.InteropServices;

namespace System.Runtime.Serialization
{
  /// <summary>
  /// Assists formatters in selection of the serialization surrogate to delegate the serialization or deserialization process to.
  /// </summary>
  [ComVisible(true)]
  public class SurrogateSelector : ISurrogateSelector
  {
    private Hashtable Surrogates = new Hashtable();
    private ISurrogateSelector nextSelector;

    /// <summary>
    /// Adds a surrogate to the list of checked surrogates.
    /// </summary>
    /// <param name="type">The <see cref="T:System.Type"/> for which the surrogate is required.</param><param name="context">The context-specific data. </param><param name="surrogate">The surrogate to call for this type. </param><exception cref="T:System.ArgumentNullException">The <paramref name="type"/> or <paramref name="surrogate"/> parameter is null. </exception><exception cref="T:System.ArgumentException">A surrogate already exists for this type and context. </exception>
    public virtual void AddSurrogate(Type type, StreamingContext context, ISerializationSurrogate surrogate)
    {
      if (type == null || surrogate == null)
        throw new ArgumentNullException("Null reference.");
      string str = type.FullName + "#" + context.ToString();
      if (this.Surrogates.ContainsKey((object) str))
        throw new ArgumentException("A surrogate for " + type.FullName + " already exists.");
      this.Surrogates.Add((object) str, (object) surrogate);
    }

    /// <summary>
    /// Adds the specified <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> that can handle a particular object type to the list of surrogates.
    /// </summary>
    /// <param name="selector">The surrogate selector to add. </param><exception cref="T:System.ArgumentNullException">The <paramref name="selector"/> parameter is null. </exception><exception cref="T:System.Runtime.Serialization.SerializationException">The selector is already on the list of selectors. </exception><exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception>
    public virtual void ChainSelector(ISurrogateSelector selector)
    {
      if (selector == null)
        throw new ArgumentNullException("Selector is null.");
      if (this.nextSelector != null)
        selector.ChainSelector(this.nextSelector);
      this.nextSelector = selector;
    }

    /// <summary>
    /// Returns the next selector on the chain of selectors.
    /// </summary>
    /// 
    /// <returns>
    /// The next <see cref="T:System.Runtime.Serialization.ISurrogateSelector"/> on the chain of selectors.
    /// </returns>
    /// <exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception>
    public virtual ISurrogateSelector GetNextSelector()
    {
      return this.nextSelector;
    }

    /// <summary>
    /// Returns the surrogate for a particular type.
    /// </summary>
    /// 
    /// <returns>
    /// The surrogate for a particular type.
    /// </returns>
    /// <param name="type">The <see cref="T:System.Type"/> for which the surrogate is requested. </param><param name="context">The streaming context. </param><param name="selector">The surrogate to use. </param><exception cref="T:System.ArgumentNullException">The <paramref name="type"/> parameter is null. </exception><exception cref="T:System.Security.SecurityException">The caller does not have the required permission. </exception><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter"/></PermissionSet>
    public virtual ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector)
    {
      if (type == null)
        throw new ArgumentNullException("type is null.");
      ISerializationSurrogate serializationSurrogate = (ISerializationSurrogate) this.Surrogates[(object) (type.FullName + "#" + context.ToString())];
      if (serializationSurrogate != null)
      {
        selector = (ISurrogateSelector) this;
        return serializationSurrogate;
      }
      else
      {
        if (this.nextSelector != null)
          return this.nextSelector.GetSurrogate(type, context, out selector);
        selector = (ISurrogateSelector) null;
        return (ISerializationSurrogate) null;
      }
    }

    /// <summary>
    /// Removes the surrogate associated with a given type.
    /// </summary>
    /// <param name="type">The <see cref="T:System.Type"/> for which to remove the surrogate. </param><param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> for the current surrogate. </param><exception cref="T:System.ArgumentNullException">The <paramref name="type"/> parameter is null. </exception>
    public virtual void RemoveSurrogate(Type type, StreamingContext context)
    {
      if (type == null)
        throw new ArgumentNullException("type is null.");
      this.Surrogates.Remove((object) (type.FullName + "#" + context.ToString()));
    }
  }
}

Natively support buttons in the inspector

For example, it would be nice if defining a button in the inspector was as simple as:

class Item {
    [Button]
    void InvokedMethod() {
        Debug.Log("hello from " + this);
    }
}

Right now, this can be done (and is included in one of the samples), but the process is painful and doesn't work as nicely. This requires direct integration into TypeMetadata and the ReflectedPropertyEditor.

One potential issue with this is ordering. Reflection will not give the order of fields/properties/methods in the same order they are declared as. This can be resolved by explicit ordering via the Order attribute.

Automatic reference object instantation

When a new object has been created, it may contain a number of reference fields. What should happen in this scenario?

  • Should these reference fields be automatically instantiated?
  • What if the reference type is an interface / abstract type?
  • What about nested references?

The current behavior is to leave these references as null, and just assume the user will take care of it. However, perhaps the inspector should require the user to manually construct reference instances (this would also help the inspector deal with recursive class definitions).

CreateInstance() does not properly create ScriptableObjects

TypeMetadata class needs to check to see if it is a ScriptableObject type and create the instance via the ScriptableObject.CreateInstance method. I threw a sub optimal check for this locally on Line 81 of TypeMetadata.cs

    if (typeof(UnityEngine.ScriptableObject).IsAssignableFrom(ReflectedType)) {
        return UnityEngine.ScriptableObject.CreateInstance(ReflectedType);
    }

Compile Errors with Visual Studio 2012

When using Visual Studio 2012 to code for Unity with Full Inspector 1.10 installed, it's throwing compile errors with the UnityEngine side of things which blocks it from ever compiling the UnityEditor, thus you never get a chance to see if your code is throwing any errors in the Editor.

Best I can tell is that this is due the dll being compiled with a different .net version, however after trying all the different versions, I'm a bit stuck.

Warning 1   The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias; using definition from 'c:\Users\r.caltabiano\Documents\WordSearch\Assets\FullInspector\FullInspector\Serializers\JsonNet\DLLs\Newtonsoft.Json.dll'  C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   2   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   3   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   4   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   5   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   6   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   7   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp
Error   8   Missing compiler required member 'System.Runtime.CompilerServices.ExtensionAttribute..ctor' C:\Users\r.caltabiano\Documents\WordSearch\CSC  UnityVS.WordSearch.CSharp

Possiblity of adding support for multiple "BaseBehavior" serializers

I know it's better to stick to one type of serializer throughout the entire project, but this was a request from someone on my team higher than me.

Example:

    public class ProtoBehavior : BaseBehavior<ProtobufNetSerializer> { }
    public class JsonBehavior : BaseBehavior<ProtobufNetSerializer> { }

Remove Ref<T>

Consider removing Ref<T>. This is the biggest stumbling block with Full Inspector and is non-intuitive. Ref<T> is used internally within serialization to disambiguate between references to UnityEngine.Objects and an actual serialized UnityEngine.Object.

The proposed alternative is require [SerializeField] or similar annotations only on the UnityEngine.Object derived type, where all other types use the serialization library of choice. For example,

[JsonObject(MemberSerialization.OptIn)]
struct MyStruct<T> {
    [JsonProperty]
    public T Value;

    [JsonProperty]
    public GameObject MyObject;

    [JsonProperty]
    public MyBehavior MyBehavior;
}

class MyBehavior : BaseBehavior<JsonNetSerializer> {
    [SerializeField]
    private MyStruct<float> Data;
}

This causes a loss of serialization customization over MyBehavior and requires custom reflection over behavior types to discover which properties to serialize. However, it means that whenever a serializer encounters a UnityEngine.Object reference it knows it is always serialized as a reference.

This will break current serialization data.

Collapsible Objects

Unity, by default, shows [Serializable] classes in a collapsible subsection. Full Inspector should mimic this behavior as much as possible.

About following Unity3D field display rules

From a quick look around it seems that in version 1.2, we now need to use [ShowInInspector]. However, some properties are shown even without the attribute, while others are not. I'm confused?

Isn't [ShowInInspector] redundant with [JsonProperty] anyway though? I could see [JsonProperty] being the equivalent of Unity's [SerializeField], defaulting to being shown in the inspector but with the option to hide it with [HideInInspector]. That covers everything we need, no?

Hmm, I just realized you probably did this to decouple serialization from inspection so we can plug in the serialization framework of our choice. However I still think we should try to find a more consistent solution because it is confusing as it is.

If types (even primitives, strings, vectors, etc.) were all hidden by default, it would be
fine by me. As long as it's consistent.
#13

Foldout for structs

It would be nice to have, but requires a rework of the editor metadata storage system

Unable to inject ScriptableObjects in a property

I'm stuck trying to inject custom ScriptableObject assets in a script. Maybe I'm just doing something wrong. I have the following asset definition:

[JsonObject(MemberSerialization.OptIn)]
public class SpellDescriptor : BaseScriptableObject
{
    [MenuItem("Assets/Create/SpellDescriptor")]
    public static void CreateAsset()
    {
        ScriptableObjectUtility.CreateAsset<SpellDescriptor>();
    }

    [JsonProperty]
    public string spellName { get; private set; }

    [JsonProperty]
    public int manaCost { get; private set; }
}

Then I have a SpellCaster component in which I want to be able to inject a spell descriptor

[JsonObject(MemberSerialization.OptIn)]
public class SpellCaster : BaseBehavior
{
    [JsonProperty]
    private Ref<SpellDescriptor> spellDescriptor { get; set; }

    void Start()
    {
        Debug.Log(spellDescriptor.Value); // prints out Null
    }
}

At design time, I drag-and-drop the asset I created onto the spellDescriptor property of my SpellCaster. Sadly, when I start the game, I get the following warning:

Json.NET had an error. Continuing with deserialization.
Exception: System.InvalidCastException: Cannot cast from source type to destination type.

So the spellDescriptor property stays null at runtime, and even goes back to "None" in the editor.

I use this script to create ScriptableObjects: http://wiki.unity3d.com/index.php?title=CreateScriptableObjectAsset

C# properties on Prefabs do not sync

Gameobjects created from a prefab with the following behavior don't sync with the prefab like you would expect. For example, changing someInt in the prefab should be reflected in the gameobject, but it's not.

using UnityEngine;
using FullInspector;

public class SomeBehavior : BaseBehavior
{
    [SerializeField]
    [ShowInInspector]
    private int someInt { get; set; }

    [SerializeField]
    [ShowInInspector]
    private float someFloat { get; set; }
}

Note that if you replace each C# property by a normal field of the same type, it behaves as expected. Well, except that out-of-sync fields aren't emphasized in bold like in the default inspector. That would be nice too :)

The object reference array in BaseBehavior keeps growing after every inspection change

For BaseBehavior derived scripts that reference unity objects with Ref<>, the inspector code keeps adding new object references when doing completely unrelated changes in the inspector view. Anytime you edit a property in the script's inspector, a new object reference is added at the end of the array and the old one is not discarded. The serialized state always points to the most recent one.

This looks like unnecessary bloat, perhaps I'm wrong though. You can see what I'm talking about by activating the debug view mode of the standard inspector.

Changing the type of a field does not clean up the persisted data

When changing the signature of a serialized field (e.g. changing its type), its old data is persisted and causes errors if the new type doesn't match the existing data. The old data can't seem to be overwritten unless you change the signature back so the type matches.

2d char array property setter error

This will error out in Editor as soon as you uncomment the setter to the char this[...] property.

Example Class:

using UnityEngine;
using FullInspector;
using Newtonsoft.Json;

[JsonObject(MemberSerialization.OptIn)]
public class CharTest : BaseBehavior
{
    public int sizeX;
    public int sizeY;
    public char[,] grid;

    protected override void Awake()
    {
        base.Awake();
        grid = new char[sizeX, sizeY];
    }

    public char this[int x, int y]
    {
        get { return grid[x, y]; }
        // set { grid[x, y] = value; }
    }
}

Exception Details:

ArgumentException: method argument length mismatch
System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:226)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method, Boolean throwOnBindFailure) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:291)
System.Delegate.CreateDelegate (System.Type type, System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System/Delegate.cs:295)
System.Reflection.MonoProperty.CreateGetterDelegate (System.Reflection.MethodInfo method) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:274)
System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) (at /Users/builduser/buildslave/monoAndRuntimeClassLibs/build/mcs/class/corlib/System.Reflection/MonoProperty.cs:291)
FullInspector.Utilities.PropertyMetadata.Read (System.Object context) (at Assets/FullInspector/FullInspector/Utility/Forge/PropertyMetadata.cs:61)
FullInspector.PropertyEditors.ReflectedPropertyEditor.GetElementHeight (UnityEngine.GUIContent label, System.Object element) (at Assets/FullInspector/FullInspector/Editor/PropertyEditors/Special/ReflectedPropertyEditor.cs:221)
FullInspector.FullInspectorCommonSerializedObjectEditor.OnInspectorGUI () (at Assets/FullInspector/FullInspector/Editor/FullInspectorCommonSerializedObjectEditor.cs:63)
UnityEditor.DockArea:OnGUI()

The foldout for struct and non-null abstract properties is missing

Since I updated to version 2.0, struct and non-null abstract properties don't show a foldout anymore. See the following code. Full Inspector should show a foldout for the someStruct property but it doesn't.

[JsonObject(MemberSerialization.OptIn)]
public struct SomeStruct
{
    [JsonProperty]
    [ShowInInspector]
    private int someInt { get; set; }

    [JsonProperty]
    [ShowInInspector]
    private float someFloat { get; set; }

    [JsonProperty]
    [ShowInInspector]
    private string someString { get; set; }

    [JsonProperty]
    [ShowInInspector]
    private Color someColor { get; set; }
}
public class SomeBehavior : BaseBehavior
{
    [SerializeField]
    [ShowInInspector]
    private SomeStruct someStruct { get; set; }
}

Note that replacing SomeStruct with a class instead, it does work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.