Interface Serialization - ManeFunction/ManeTools-Unity GitHub Wiki

The package has two different attributes for interface serialization. Both are Property Drawers.

SerializeInterface

To serialize data structures (plain C# types), use [SerializeInterface] with [SerializeReference] on an interface or a base class. The two attributes work only together. This provides a type picker, then the nested instance fields.

Concrete classes can be nested in the component. The field type can be a base class or an interface. Mark each concrete class [Serializable]; that attribute is not inherited. A nested class has no public parameterless constructor. The drawer calls the generated constructor. It passes the inspected component when that component is the outer type, and null otherwise.

using Mane.Unity;
using UnityEngine;

public class Lodout : MonoBehaviour
{
    [Serializable]
    public class BaseWeapon
    {
        public int Damage;
    }

    public interface IWeapon { }

    [Serializable]
    public class Bow : BaseWeapon, IWeapon
    {
        public int Range;
    }

    [Serializable]
    public class Sword : BaseWeapon, IWeapon
    {
        public int Speed;
    }

    [SerializeReference, SerializeInterface]
    private IWeapon _weapon;

    [SerializeReference, SerializeInterface]
    private BaseWeapon _equipped;
}

SerializeInterface example

InterfaceOnly

[InterfaceOnly(typeof(IFoo))] on a [SerializeField] UnityEngine.Object (usually a MonoBehaviour) requires the assigned object to implement the interface. This is for scene/prefab references. The field type can be MonoBehaviour or a specific behaviour.

using Mane.Unity;
using UnityEngine;

public class TestComponent : MonoBehaviour
{
    [SerializeField, InterfaceOnly(typeof(IDamageable))]
    private MonoBehaviour _source;
    
    [SerializeField, InterfaceOnly(typeof(IDamageable))]
    private EnemyBehaviour _target;
}

InterfaceOnly example