Generic classes in Unity

C#

Generic classes in Unity

 

When I was writing my post about MVC in Unity last week I realized that I used a lot of – let’s say nonbasic stuff, that might be kind of confusing if you are new to programming. So here a very short guide to generic classes in Unity and when they might be useful to you.

 

What do generic classes do?

Generic classes or generic methods have a parameter type, but you are not specifying the type of that parameter. Now what would you use that for? I guess that’s best illustrated by an example. I’m a big fan of the List class, but one thing that I often use in games and which is not defined by the List class is the swapping of two objects. Now since I am way too lazy to write a method in every class that needs that feature, I’d rather extend the List class itself. The problem there is, that a List can be of different types. You can have a List of ints, a List of floats, a list of Transforms, the list goes on. (Haha, list pun. Sorry, but not sorry.) So this wouldn’t do for me, because it only works for ints:

public static void Swap(List list, int indexA, int indexB)
{
    int tmp = list[indexA];
    list[indexA] = list[indexB];
    list[indexB] = tmp;
}

By using a generic method, I can make the Swap method for every type of list:

public static List Swap(this List list, int indexA, int indexB)
{
    T tmp = list[indexA];
    list[indexA] = list[indexB];
    list[indexB] = tmp;
    return list;
}

// access the method like this:
// List myList = new List() { 8, 3, 2, 4 };
// myList = myList.Swap(1, 2);

In this example, T could be any type, GameObject, bool, whatever you want. It also shows that List by itself is a generic class. That’s why you have to declare Lists like that:

public List listOfInts;

You’re declaring that you wanna give your instance of the generic class List the type int.

 

Practical uses in games

Now when you are coding games, generic classes and methods are also useful for other things. I used it for my MVC system, but it can also be very nice otherwise, for example if you have classes that are always paired together, but there are subtypes of those classes.
So let’s say you are coding a Star Wars game. In Star Wars, many spaceships have cute droids, which will repair them in flight. But there might be different types of spaceships, and of course also different types of droids. So first, I’ll prepare the base classes for both:

public class BaseSpaceship : MonoBehaviour
where D: BaseDroid
{

    public D myDroid;

    private void OnLowHealth () {
        myDroid.RepairShip();
    }

}
public class BaseDroid : MonoBehaviour {

    public void RepairShip () {
        //Repair the ship and get shot while doing it, or isn't it how this works?
    }

}

So the BaseSpaceship already has defined myDroid. But we don’t know what kind of droid it will be. Still, we can call the RepairShip() method on the BaseDroid, which every droid is able to do. But we also wanna build the SpaceShipA, which is a spaceship which always is paired with a BB-8 unit.

(Please don’t get angry dear Star Wars nerds, BB-8 units probably don’t get used on vehicles, but I just wanna state a point here and BB-8 is really cute…)

And BB-8 of course has this awesome feature we all love, that he can pull out a lighter. So we want to access that with our spaceship:

public class SpaceShipA : BaseSpaceship {

    public void ThumbsUpToBB () {
        myDroid.PullOutLighter();
    }

}
public class BBEight : BaseDroid {

    public void PullOutLighter () {
        //So cuuute <3
    }

}

Like this, the SpaceShipA is aways paired with a BBEight, and can therefore access its special BB-8 features, while still doing the other things that BaseSpaceShips and BaseDroids do.

 

Difference to interfaces

Interfaces do get used quite frequently and do almost the same. The difference is, that with the interface I can only access the things the BaseDroid does, while I can access all the methods of BBEight if I do it through a generic class, which is quite nice in my eyes.

 

Downsides

Now that sounds all very practical, but there unfortunately are also some limitations in Unity. Undefined generic classes for example can not be serialized. In our example that means that you can’t add BaseSpaceship to a GameObject or placed on a public variable in the editor, since its droid is not defined. Even if you don’t wanna add any additional features to the BaseSpaceship, you still have to create a class inheriting from BaseSpaceship with a defined drone type to be able to use it in the editor.
Whit that said, I still think it is a very useful feature and well worth to use it, in the proper situations of course 🙂

1 COMMENT
  • Warder
    Reply

    Hi, i have some question about creating generics class and inheritance it off MonoBehaviour. Like here
    public class BaseSpaceship : MonoBehaviour
    where D: BaseDroid

    Is it still available? I mean in Unity 5.6.2f1
    The same problem I have in your another guide MVC in Unity

Leave a Reply

Your email address will not be published. Required fields are marked *