Unity can’t serialize interfaces. But sometimes you want to have access to any component, as long as it implements an interface. They are incredibly useful in game development, particularly if you’re coding for reuse. So what can you do? There’s a fairly lengthy workaround. You create a serialized Unity property for a GameObject. Then you create a second property (this time not serialized) for your interface. You use the interface property’s getter to get a component from the GameObject property that implements your desired interface.
I found myself writing this fairly lengthy code so often, I’ve turned it into my own Visual Studio snippet. Since I use it so much, maybe you will too. The code you’ll need is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
[SerializeField] private GameObject privateGameObjectName; public GameObject PublicGameObjectName { get { return privateGameObjectName; } set { //Make sure changes to privateGameObjectName ripple to privateInterfaceName too if (privateGameObjectName != value) { privateInterfaceName = null; privateGameObjectName = value; } } } private InterfaceType privateInterfaceName; public InterfaceType PublicInterfaceName { get { if (privateInterfaceName == null) { privateInterfaceName = PublicGameObjectName.GetComponent(typeof(InterfaceType)) as InterfaceType; } return privateInterfaceName; } set { //Make sure changes to PublicInterfaceName ripple to PublicGameObjectName too if (privateInterfaceName != value) { privateGameObjectName = (privateInterfaceName as Component).gameObject; privateInterfaceName = value; } } } |
Obviously swap privateGameObjectName, PublicGameObjectName, privateInterfaceName and PublicInterfaceName property names with ones suitable to your situation, and swap InterfaceType to the interface you want to use. After that, usage is as simple asĀ PublicInterfaceName.DoWhateverInterfaceFunctionYouWant()