Inspector interface serializer I've written some code that allows Unity3D's inspector to display fields that conform to an interface. Unity has some quirks about their inspector, so as a preface they are listed here:


If you add a [Serializable] attribute to a class, Unity's Inspector will attempt to show all public fields inside that class.
Any class extending Monobehaviour automatically has the [Serializable] attribute
Unity's inspector will attempt to display any private field with the [SerializeField] attribute.
Unity's inspector will not attempt to display generic types or interfaces, with the exception of List&lt;T&gt;, which is hard-coded.
Unity's inspector will not attempt to display properties. A common workaround is to have a private backing field for your property with [SerializeField] attached. Setters won't be called on the value set in the inspector. It's typically only set pre-compilation time, although a developer can modify values in the inspector during runtime. Currently it is acceptable to me to only take the initial value, although if anybody has a simple and efficient way to update successfully, I'd be happy to hear it.
Unity has a PropertyDrawer class you can extend to control how a type is displayed in the inspector. The PropertyDrawer for an interface or generic type will be ignored.


The code

UnityInterfaceHelper.cs

[Serializable]
public class UnityInterfaceHelperBase
{
    [Tooltip("The component that is of the type required.")]
    [SerializeField]
    public Component target;
}

[Serializable]
public class UnityInterfaceHelper&lt;TInterface&gt; where TInterface : class
{
    public TInterface TargetAsInterface
    {
        get
        {
            if (targetAsInterface == null)
            {
                targetAsInterface = target as TInterface;
            }
            return targetAsInterface;
        }

        set
        {
            if (targetAsInterface != value)
            {
                targetAsInterface = value;
                if (value as Component != null)
                {
                    target = targetAsInterface as Component;
                }
            }
        }
    }

    [Tooltip("The component that is of the type required.")]
    [SerializeField]
    private Component target;

    private TInterface targetAsInterface;

    public static implicit operator UnityInterfaceHelper&lt;TInterface&gt;(UnityInterfaceHelperBase b)
    {
        return new UnityInterfaceHelper&lt;TInterface&gt;()
        {
            target = b.target
        };
    }

    public static implicit operator UnityInterfaceHelperBase(UnityInterfaceHelper&lt;TInterface&gt; b)
    {
        return new UnityInterfaceHelperBase()
            {
                target = b.target
            };
    }
}


UnityInterfaceHelperPropertyDrawer.cs

[CustomPropertyDrawer(typeof(UnityInterfaceHelperBase), true)]
public class UnityInterfaceHelperPropertyDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        label = EditorGUI.BeginProperty(position, label, property);

            position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
            EditorGUI.PropertyField(position, property.FindPropertyRelative("target"), GUIContent.none);

        EditorGUI.EndProperty();
    }
}


Typical usage

[SerializeField]
private UnityInterfaceHelperBase itemComparable;

public IComparable ItemComparable
{
    get { return ((UnityInterfaceHelper&lt;IComparable&gt;)itemComparable).TargetAsInterface; }
    set { ((UnityInterfaceHelper&lt;IComparable&gt;)landedComparable).TargetAsInterface = value; }
}

public void CompareItems()
{
    if(ItemComparable.CompareTo("Hello") == 0)
    {
        Debug.Log("Hello world!");
    }
}


I'm looking to reduce the amount of code I have to repeat for every property, it's already down quite a way, but I'm hoping to make it as simple as possible, but any other comments on the code are welcome too.
Possible bug:

If you get the value, targetAsInterface is initialized. One can then set the value to something that is not a Component. Like null. 

If you then get the value again, you'll get the old value of target recasted to TInterface. Seems to me that this violates what get and set are supposed to do.