So I wrote a post a while ago explaining inheritance in Unreal Engine. I got a lot of great feedback on that post. A lot of people liked it but a lot of people also complained that I didn’t go into components at all and only presented the inheritance side of the great inheritance versus composition war. It was my intent at the time to do a part 2 not long after that original post but somehow two thirds of a year flew right by me. Better late than never right? Anyway welcome to …
Composition In Unreal Engine
“I will always choose a lazy person to do a difficult job because a lazy person will find an easy way to do it.”
*Probably not the exact quote. The internet has like 6 different versions of this same quote.
Writing lots of code sucks. It especially sucks if it’s basically doing something you’ve already written code to do some place else. Being able to re-use code is an important tool in the arsenal of any decently lazy developer out there. I’ve gone over how you can avoid writing duplicate code by using inheritance, but that’s not the only way, and in a lot of cases it’s not even the best way.
Let’s take another look at that great zombie family tree diagram from last time.
So in this example the bottom row of zombies have hats and green coloring because they inherit from a zombie that was green and had a hat. The code for the green coloring and the code for the hat live in a different class that the bottom row of zombies just inherit.
Now lets imagine that you want a green zombie not wearing a hat. Because the code to generate the hat lives in a deeper level of inheritance than the code for the hat does there’s no clean way to make that happen. It is possible to inherit from green zombie with a hat and then either overwrite the hat or write code to remove the hat once the game begins, but then we are writing code to negate other code we have already written and the whole thing starts to look pretty messy. Writing code to negate other code you’ve written really isn’t the good lazy way to do things.
Now imagine you’ve got another big character in your game besides all the oddly dressed zombies. Let’s say it’s the protagonists love interest. It could be anybody but for the sake of argument lets just say its Lauren Cohan from the hit TV show The Walking Dead:
I know this post took a strange turn just there but hang in here. Let’s say for the sake of the game’s story love-interest-Lauren-Cohan has to wear a hat. This theoretical game just won’t make any sense without it. You don’t want to rewrite the hat generating code from the zombies on love-interest-Lauren-Cohan because that’s rewriting code. You also don’t really want love-interest-Lauren-Cohan to inherit from some zombie class. I mean think about it. Would you want to date someone was at least partially zombie? Who knows what other necrotic code she might accidentally inherit.
What if instead of inheriting hats we wrote a separate class for hats and gave it to the zombies who needed them and kept it away from the zombies that didn’t. We could also give love-interest-Lauren-Cohan a hat without fear of zombie contamination.
Now in practice if you are writing a game it’s actually really unlikely that you’d have code generate a hat. You’d probably just use a static mesh for that. But it was a useful visual device for me to explain components(plus now I’ve siphoned off a little of that sweet sweet Lauren Cohan fan traffic). You can use a component class, in this example the hat, to add shared functionality to classes that don’t share inheritance.
Let’s look at an actual implementation.
So in one of my VR projects that I’m working on right now a common piece of functionality a prop might have is that it’s able to be picked up by the player. Because the objects the player will be interacting with will vary wildly I don’t want to have to make every object inherit from the same base class, but I can make a component for grab-able objects and drop it on anything I want to give that functionality. This is actually pretty simple in Unreal. It can even be done using only blueprints.
First let’s create our component class. Open the create blueprint class dialog box and select “Scene Component” for the parent class.
The first thing I do in any component classes I create, as a rule of thumb, is to store a reference to to root of the actor it’s attached to. This isn’t necessarily something you always need to do, but I’ve yet to create a component that didn’t need that at some point, so I’ve just found it easier to grab right up front.
Note that you have to store the root as a “Primitive Component” type. Now all I do is expose two public functions another actor can call for picking the item up
… and putting the item down.
These can be called from anywhere. In my case it’s called from a class attached to the motion controller on the player. When I attempt to “grab” an item I just check if it has this component attached. If it does I call the corresponding public function.
An added benefit of composition is that I can add these components to anything. That includes static meshes and instances of classes. If you select an instance of a static mesh in your scene you can just drag and drop any component right on to it.
It also allows you to set public variables that can be changed in the specific instance. In the example below I have a component I use for clues attached to a static mesh. On that instance I’ve filled out the public variable for “Clue Data” for that specific clue without needing to create clue specific actor class.
The idea behind composition is that you make your classes out of a combination of other smaller classes. This allows you to reuse code without needing to worry about what inherits from what. So how do you chose which method to go with? The old saying is “Composition over inheritance”. If you aren’t sure what route to go I recommend using composition. Personally I use a mix of both. Inheritance can have it’s place. I tend to use inheritance whenever I’m making something more specific. For instance if I theoretically had a class for cats, but then I needed a class for tabbies, I’d probably just make tabbies inherit from cats. Tabbies will always be cats, just a more specific form of cats. I find that as long as you are just narrowing down a class inheritance is just fine. That having been said it’s highly likely my class for cats would contain components used for movement, purring, and AI. At the end of the day it really comes down to your personal judgment though.