Property draw a class that has a generic type

There isn’t much to say… I just want to know if it’s possible to property draw a class that has a generic type. If the answer is no just say no (I don’t really need an alternative solution, so I don’t need to add more detains. I have a different solution, but I don’t like it), if it is so how am I suppose to do it?

edit(Moved from answer):

I will just specify what I want, because my other answer won’t work:

I have a class called “Attack”, which contains some properties an attack has (such as a name, or a cost), and a delegate, which is the method being called when attacking. The delegate is a delegate called “VoidFunc” (when I made it I didn’t know about the Action delegate, and what I made is basically a Func delegate without a return type). The Attack class has a few overloads, each one adds one generic, and that generic is the generic type in the delegate. Here is an example for one with one generic type:

[System.Serializable]
public class Attack<T>
{

    public string name;
    public int cost;
    public VoidFunc<T> attackMethod;
    
}

Now I need to make a custom property drawer for this. I have a non-generic overload, which worked perfectly fine, but it is not what I need. My initial attempt was this:

[CustomPropertyDrawer(typeof(Attack<T>))]
public class AttackPropertyDrawer<T> : PropertyDrawer

But apparently you can’t use generic types in attributes (I would actually like to know the logic behind it)… So I tried instead of making the class generic and put the generic type in the Attack type, just use the object keyword, meaning I will do “Attack”. But it didn’t work… So I tried something else, to test if it’s even possible to draw generic classes… Let’s say I made an Attack, ok? So then when I property drawn it, I used “Attack”. It still didn’t work. So the problem must be Unity’s support to it. I came to the forum and got @jdean300’s answer, which also didn’t work. I now had that different solution of using “object” at the attack class, but I can’t overload a variable. So do you have any other solution? The ONLY solution I have left is to use the “object” keyword at the delegate declaration, but I’d prefer almost ANY other solution to do it.

Unity 2020. Still in alpha, but I’m never going back. It was just like this in 2018.3 with Nested Prefabs. WOO!

If you have this for example, as a data class:

using System;
using UnityEngine;

[Serializable]
public class Blah<T> {
	[SerializeField] private T value;
}

Then you can use the following code snippet for your PropertyDrawer.

using UnityEditor;
using UnityEditor;

[CustomPropertyDrawer(typeof(Blah<>))]
public class BlahDrawer : PropertyDrawer {
	//... (your typical PropertyDrawer stuff here).
}

Just note your PropertyDrawer should NOT be generic itself, but you can use typeof(Blah<>) without any type in between the angle brackets, to specify any type can go there. This is confirmed to work in Unity 2020.1.0a18 as of today, and thank the heavens.

It’s possible with a bit of hacking. The generic class that you want to create a property drawer for needs to inherit from a non-generic base class, and then you can create a property drawer for the non-generic class.

public class NonGenericBase {}

public class GenericType<T> : NonGenericBase {}

[CustomPropertyDrawer(typeof(NonGenericBase ))]
public class NonGenericBaseDrawer {}

Unity’s serialization system doesn’t support serializing generic types except the generic “List” type. The inspector can only edit things that are serializable by Unity.

edit
Since you have added more details i will get a more detailed answer.

Again, Unity doesn’t support serializing generic types. Furthermore delegates can’t be serialized by Unity in general. Unity now supports a special delegate wrapper type called “UnityEvent”. This class is defined in the “UnityEngine.Events” namespace.

Unity also implemented a generic version of that class in order to specify event parameters. However as i said Unity doesn’t support generic types, that’s why you have to create a concrete type out of the generic type in order to be serializable.

[System.Serializable]
public class EventWithStringParam : UnityEvent<string> { }

You can use generic base classes but the final classes and types that are used have to be concrete, non-generic types if you want them to be serializable and to be viewable / editable in the inspector.

Make sure you read the UnityEvent documentation carefully, especially the last paragraph about the generic type.