Download

What is the best approach for a polymorphic function that finds all sockets in any given instance of a child class, where said child classes will have different numbers of socket?

'm a computer science student going into my 4th year. I’ve become increasingly interested in development as a career. As such, I’ve been working on a game over the summer to teach myself unreal engine 4. I’m currently working on a simple RTS game to learn about game design. The units in my game are mechs (who doesn’t love giant robots?). One of the features I have been working on implementing is a modular weapons system. Before I explain the issue that I am trying to solve, let me briefly explain the class hierarchy, as it will better frame my issue.

I have a single abstract base class written in C++. This class defines all the basic data and behavior that a mech should have and do. It also provides implementations for several of these behaviors, such as movement, stat changes, getters, setters, etc. Each derived class will be a blueprint class as these will need actual meshes and animations. Note that the base class inherits from ACharacter. It does know that a mesh exists.

I want each derived class to define for itself how many weapons it can be fitted with. Further, I want certain weapon slots to only accept their respective type of weapon. Since each mech will define their own slots and where they are to go on the mesh, it seems like mesh sockets are a good choice for mounting the weapon actors onto the mech actors. These can be defined on the mesh; therefore being also defined in the blueprint (in an indirect way). I have used the convention “weapon_n” where n is some integer to name each of the sockets. My approach to finding the sockets within the code is to use a for loop. Each loop creates an FName with value “weapon” + std::to_string(idx).

Here is my issue. I want to have the base class provide functionality for interacting with these weapon slots, which amounts to interacting with specific sockets. This is to support polymorphism. I’m not creating the sockets in the editor. This means that I must search for the sockets by name each time I need them (it occurs to be that I could do this once on BeginPlay(), and store them in some container for reference later). Further, my current naming convention makes distinguishing sockets meant for different weapon types difficult. I could add prefixes to the socket names {heavy, light, special…} but now my approach to finding the sockets would require searching for every combination of number and prefix. That’s bad code.

The solution that I think makes sense, is to use a struct. The struct will contain the socket name, and the weapon that is attached, if any. I will store these structs in an array, that is stored by each unit (the array will be defined in the base class, populated in the derived). Each derived class will provide its own code for finding and populating its weapons array.

You could also create a scene component that does something similar. In your Blueprint editor you can put your scene components in whatever spots you like on your mech relative to its skeletal mesh, and those can be attached to sockets you add on the mesh if you’d like, or be relative to bones.

You can put all sorts of options in your weapon attachment scene components, and also have subclasses of them that do some special extra logic. In the end, it’d be very easy to create a modular system where a lot of the logic lives in each component.

And because they’re scene components, you can create hierarchies of them, or attach them to any other scene components, or attach other scene components to them. Lights, Particle Systems, Meshes, etc… And their transforms will properly update, so the weapons will follow. And you can create a weapon actor that has all the scene components and attach it to your weapon slots on the mech. Then your weapon logic could trigger a muzzle flash particle system on your attached weapon actor, for example, whenever it’s fired.

This is a strong idea. This completely eliminates the need for a “WeaponSlot” struct or class. I can store these components in an array with each instance of a unit, and I don’t have interact with the sockets at runtime. Thanks very much for the suggestion!