Child classes vs Components?

Hi, so I’m used to creating everything in a hierarchy E.G making a generic character class that does everything that pertains to all creatures, like health, movement, mesh, collision, physics, etc, then making a player character that makes use of the movement through inputs, and a different child class that handles AI, so that I only have to do the universal things once.

Well, my current project started out as just an experiment so I didn’t plan the hierarchy out ahead of time, but now it’s evolved a lot from there. Now all the player functionality is in a single class, including things that should be inherited and available to things like NPCs and enemies as well, like how damage is handled, death states, animations, movement, etc, and now I want to do create an enemy class.

At first I thought I’d just create a new character class, move the general stuff in there, put the player relevant code in a new player class that inherits from the character, and have the have the player blueprint reparented. But if I reparent things now, all the work I’ve put into the blueprints is pretty much guaranteed to break, which is a lot of experimental and time consuming tweaking. So I thought why not keep the current class, but break the situational stuff off into components?

So what I could do is keep the current character class, but split of the player controls into a player controller component, then just have all the player relevant variables in blueprint refer to the component instead of the character class. That way I could also define NPC/Enemy/AI controls in a component, and just attach that to the generic character class if I want the AI to take control of a particular pawn. Basically treating control and actions similarily to how you would attach collision components, camera components etc.

What would be the downside of this other than an unconvential way of organizing these kinds classes?

I’m not sure where you got the idea that this is an unconventional method of organizing a class. While Unreal does tend to push inheritance in a few places, a lot of what it does is through components for many of the reasons that you’ve laid out for wanting to do it.

The way you’re used to doing it was also the way that the games industry primarily did things but there has been a big push towards components in the twenty years because creating objects through composition can be more flexible than trying to build an inheritance tree. Especially when you limit yourself to single inheritance (excluding interfaces) the way Unreal and many other C++ codebases do.

It’s worth doing some research on your own. “Composition vs Inheritance” would be a general topic. Another popular one is call ECS, or Entity Component Systems. There are a lot of variations in that case and many of the reasons for it have more to do with low level CPU gains but the topic itself is interesting and could give you some ideas as to how to organize your own systems because there in that case everything is a component and “objects” only exist as some arbitrary collection of components.

Thanks! That’s definitely very interesting and have put things in a different perspective for me and opened up a new way to consider how to organize and reuse code.

I can definitely see how strictly following inheritance can be limiting over components. With components you can mix and match functionality as desired. Instead of having a branch of classes of creatures that have the ability to fly for instance, I could just have a single component that handles that flying capability and just add it. Seems especially useful now that BPs are so prevalent, so it would practically end up being drag and drop.

Most of my programming experience is pretty dated other than UDK (which now is dated as well of course) so I wasn’t sure if there was a big cost to components I wasn’t aware of. It’s just how I originally learned how to do it, especially in UDK.

Composition Over Inheritance.

I would say keep the inheritance limited to one more derived class other than what’s provided by the Engine out of box. Good example of this is Character Class. Make Small Single Purpose Components, ECS (Entity Component System) is different than these Actor Components in ECS data and logic is separated and it is not supported by the engine out of box you will need to integrate third party solution.

so just keeping inside the world of OOP we can use Actor Components to the fullest, make code files smaller and easier to read and manage.