This repository contains the source code for generating the Unity Source Generator DLL which allows us to use the [SerializeInterface] attribute.
The Serialize Interface Attribute allows us to serialize interfaces in Unity the same way we would use [SerializeField]
public partial class InterfaceConsumer : MonoBehaviour
{
[SerializeInterface] private IFoo foo;
private void Start()
{
foo.Test();
}
}Where the instance of 'IFoo' can be derived from a MonoBehaviour or ScriptableObject. For example, the following would be valid classes:
public interface IFoo
{
public void Test();
}
public class Foo1 : MonoBehaviour, IFoo
{
public void Test() => Debug.Log("Hello from Foo1");
}
public class Foo2 : MonoBehaviour, IFoo
{
public void Test() => Debug.Log("Hello from Foo2");
}
public class Foo3 : ScriptableObject, IFoo
{
public void Test() => Debug.Log("Hello from Foo3 (I'm a Scriptable Object btw)");
}This attribute allows us to follow the SOLID principles in Unity, by allowing us to more widely use Interfaces alongside traditional unity workflows.
This is a powerful feature as it allows us to serialize in ways not previously possible, for example, serializing a list of generic classes.
public partial class GenericInterfaceConsumer : MonoBehaviour
{
[SerializeInterface]
public readonly List<IGeneric<int>> MyGenericClasses = new();
}
public interface IGeneric<T>
{
public T Value {get;set;}
}
public class Example1 : MonoBehaviour, IGeneric<int>
{
public int Value {get;set;}
}For more use cases, it's worth checking out the Samples at Assets->Samples->SerializeInterface Sample.unity
Source Generators are created using a .net Standard 2.0 Class Library Project which is then built to a DLL. It's this DLL which is imported into Unity.
This Project can be found in the 'SerializeInterfaceGenerator' Directory.
- Load the project
\serialize-interface-generator\SerializeInterfaceGenerator\SerializeInterfaceGenerator.sln - Ensure nuget packages
Microsoft.CodeAnalysis.CSharp 4.1.0andMicrosoft.CodeAnalysis.Common 4.1.0- IMPORTANT: The version MUST be 4.1.0 and not the most recent version.
- Build the project (The DLL file should automatically be moved into the Unity Assets Folder)
The Source Generator searches for any files containting the [SerializeInterface] attribute and extends the class to support serialiation on interfaces. For example:
public partial class MyClass : MonoBehaviour
{
[SerializeInterface]
public IFoo foo;
}Will source generate the partial class:
public partial class MyClass : MonoBehaviour, ISerializationCallbackReceiver
{
[ValidateInterface(typeof(IFoo))]
private UnityEngine.Object fooSerialized;
// Required by interface.
void OnBeforeSerialize(){}
void OnAfterDeserialize()
{
foo = fooSerialized as IFoo
}
}As well as the source generator DLL we also need to include SerializeInterfaceAttribute.cs so that Unity recognizes the attribute, as well as ValidateInterfaceAttribute.cs which is what the source generator uses to ensure the correct interface is being applied.
- Improved Debugging. (We should figure out how to attach a debugger to a source generator as it's running, and more reliably view the output)
- Support for properties via
[field:SerializeInterface]usage. - Support for plain C# classes (This will require some kind of dependency injection framework)