How to couple a Type with a GameObject?

I’m kind of searching for a way to couple a specific class with a prefab.
So basically Dict<Type, GameObject>. Where in the editor I can select the Type and then tie a prefab to that Type. To then instantiate that prefab whenever I go through the list.
I know that Unity’s serialization restriction is preventing Dict<T, T> from being serialized. Though with some extension it can be made serializable.

Use case:
I’ve got a List<BaseClass> BaseClass is abstract and is always inherited.

When I want to instantiate prefabs that belong to that ClassA I’d have to serialize the prefab and use a Switch case to handle case ClassA classA: and then instantiate the right prefab.

Instead what I want to do is instantiate it through the type, like Instantiate(TypeDict[class.GetType()]); it would save me a lot of changing code constantly when a new type is introduced and always instantiates a gameobject that belongs to the type.

But the question is how to achieve a serializable dictionary Dict<Type,GameObject> where Type is restricted to anything that inherits from BaseClass
That way I can simply serialize a prefab to that type and don’t have to add more switch cases.

You can use a serializeable struct that holds the type of your class and the prefab from the game object. This struct than can be used as array or list within your hosting object. To accessing it you can use linq queries like first.

Code from Notepad++ scratch (not tested) and would require the System.Linq namespace:

[Serializable]
public struct Container
{
    public Type ClassType { get; set; }
    public GameObject Prefab { get; set; }
}

public Container[] containers;

var prefab = containers.First(c => c.ClassType == class.GetType())?.Select(c => c.Prefab);

If you want to access it with the indexer you can create a custom list type for it. See: https://docs.microsoft.com/dotnet/csharp/programming-guide/indexers/

This won’t serialize in the editor because System.Type is not serializable by default.
Also properties are not serializable either.

nvm just read your post a 2nd time. This would require another solution. In the case to make sure that Type inherited from BaseClass you might want to consider using generics.

Or a more hacky approche like this one:

var prefab = containers.First(c => c.ClassType == myclass.GetType() && c.ClassType.BaseType == typeof(BaseClass)).Prefab;

You can also use a string that represents the type. It would just change the linq query a bit (but it is risky on renaming). Properties on the other hand are serializeable on C# standards, not sure about Unity because I’m new in the Unity world.

Yeah Unity’s serialization system is quite limited.
The only way to get properties serialized is using [field: Serializable] as attribute. And even then it looks ugly in the inspector. The property must have a getter and a setter defined as well. So even more limitations.

System.Type is not serializable. But you can make it serializable by a custom serialization script / custom property drawer. Just forgot how.

Odin could probably serialize it but I only use it at home and not at work.

I guess as a workaround I’ll just generate ScriptableObject’s after the compiler reloads the scripts. So that they represent the type and hang a AssetReferenceGameObject to it or GameObject.
Then just compare the type name at runtime using GetType().Name