Serialize Generics?

I’m making an inventory system for my game, and I was wondering how I could serialize the InventoryItem class

using System.Collections.Generic;

class InventoryItem
{
  List<IAttribute> Attributes = new List<IAttribute>();

}
//This interface is used so Attributes of all data types
//Can be used in one list
interface IAttribute
{
}

class Attribute<T> : IAttribute
{
  T value;
 
  public Attribute<T>(T Value)
  {
    value = Value;
  }

  public void SetValue(T Value)
  {
  value = Value;
  }
}

You can serialize a generic class hierarchy if they all share one base class that is not generic. You can inherit a generic class from the base class, then inherit all other implementations from the generic class in the middle of the hierarchy. Unity needs the non-generic base class for serialization to work. It also needs all of the final classes to be closed, concrete implementations of the generic class. It doesn’t support serializing open, unbound generic types. To do that you would need a way of specifying the generic type argument in the inspector for each element. That would involve checking the generic type constraints and probably doing some reflection. Usually the base type would derive from ScriptableObject, in my mind, so that you can assign various instances of different types to the list by dragging and dropping them.

Your situation has another issue however, serializing an interface. You need to use the [SerializeReference] attribute to serialize interface implementations. Unity has no editor UI support for it by default because there is no way of knowing all of the potential classes that implement the interface without using reflection, and then you have to provide a picker in the inspector so that you can select which implementation of the interface to serialize because they might have to be serialized differently. Like, one may have properties that another implementation doesn’t. One may be a UnityEngine.Object, like a ScriptableObject, and another may not be. It could just be a serialized pure C# class. So, you have to either build your own custom inspector / editor support, or acquire a plugin that has already solved that issue in one way or another.

Well, actually, Unity has had TypeCache since 2019: https://docs.unity3d.com/ScriptReference/TypeCache.html

So getting all types derived from one type (including interfaces) has been as easy as one line of code for a while.

There’s honestly nothing stopping Unity from supporting this than them actually tasking someone to do so.

If Odin can do it, so can Unity.

Oh, nice tip! Yeah, maybe trying to apply reason to why it’s not supported by default is my mistake. :wink:

how can Odin do it? what attribute to use?

the example he showed wont work even with odin right? You get error:

Fields with [SerializeReference] cannot serialize objects when the field type is a generic with supplied type parameters…

That’s a limitation on Unity’s serialisation. That said, inflated generics for SerializeReference is supported in Unity versions 2023.1 and beyond.

Otherwise you’d need to use Odin serialisation.

Its till showing that I cannot use inflated types on unity 2023.2
9667472--1376936--upload_2024-2-27_15-4-9.png

9667472--1376939--upload_2024-2-27_15-4-27.png

9667472--1376942--upload_2024-2-27_15-4-38.png

Firstly, don’t use both SerializeField and SerializeReference on the same field. You should never mix up serialisation types (this includes Odin serialisation too).

Secondly, the error is probably being drawn by Odin while it’s probably serializing fine. What version of Odin are you using?