This is more a Software Engineering Answer and less a Unity Answer.
Looking at what you have for your class names I can only guess that you not after Abstract Objects but Abstract Behavior. instead of trying to use Generics for this, try and use interfaces, this is likely what your after.
What you do is you define an interface which will be describing what the implementing classes will be doing, not how as that will be determined on a per class basis. Interfaces can only have Methods and properties associated with them so no variables or data. and typically the standard convention of an interface’s name is to prefix with an “I” and postfix an “-able” or “-ible”
public interface IAttackable
{
void Attack();
}
public interface IDefendable
{
void Defend();
}
public interface ICastable
{
void Cast();
}
then you have your player class simply implement this interface.
As you can see below the Player Class is inheriting from MonoBehavior, but is now also implementing the IAttackable,IDefendable, and ICastable interfaces,Now other classes can see the player class and immediately they’ll know that Players can attack, defend, or cast.
public class Player : Monobehavior, IAttackable, IDefendable, ICastable
{
public void Attack(){}
public void Defend(){}
public void Cast(){}
}
or if the player can cast multiple spells… you can instead have the player store a List of ICastible
public class Player : Monobehavior, IAttackable, IDefendable
{
public List<ICastible> Spells;
public void Attack(){}
public void Defend(){}
public void CastSpell(int index)
{
if(Spells.Count==0)
return;
// quick way for avoiding out-of-bounds exceptions
index = index%Spells.count;
Spells[index].Cast();
}
}
the benefit with Interfaces is that now you don’t care what the implementing class actually is, just that it must be able to cast a spell to be allowed in the list. so you can have wildly different types of classes in that List (healing spells, fire spells, debuffing spells, or even special abilities which are not spells per se but can be casted) and the List only focuses on the one thing that actually cares about… the Cast() function. The Player Class doesn’t need to worry how a healing spell works, just that it can cast it. this in turn makes everybody’s life easier (the programmers and the classes itself)
And there you have it, your “generic” system that’s capable of calling methods easily.