Organizing multiple character types and their many variants?

Hi guys and gals,

I’m running a 1 man show right now doing basically everything and this kind of stuff is slowly getting way overboard…
I presently have a single blueprint for each individual enemy pawn (character model essentially)

So you can visualize this, the tree of characters:
Group1 has 5 model/mesh variants (1 ai controller 1 BT, 1 BB, 3 tasks) (weak enemy)
Group2 has 5 model/mesh variants (1 ai controller 1 BT, 1 BB, 3 tasks) (medium enemy)
special guy 1 (1 ai controller 1 BT, 1 BB, 3 tasks) (Strong)
special guy 2 (1 ai controller 1 BT, 1 BB, 3 tasks) (very strong)
special guy 3 (1 ai controller 1 BT, 1 BB, 3 tasks) (WTF strong)

All of the AIC, BT BB and Tasks are very similar with different tweaks in them for the different groups.

They all have different configurations and AI behavior patterns.

I want to add more too making the 6th set of all that, but its getting REALLY horrible to change a common thing on every single one of these all the time for slight changes and I have some major overhaul to do in the AI department. Since I am sure this won’t be the last time its time to reorganize!

Major adjustments to AI and animation handling are coming and jeez…It will take me a week to exact all these changes on each one of these.

Isn’t there a way I can have a master (6 in this case) that has all the main stuff they all have in common, and A secondary BP of some sort handling the differences?? I know there’s masters and instances with materials but I am somehow not getting how to use them properly. my head is exploding with the complexity.

I’m still using 4.9.2 because I’m afraid to migrate and break everything I have right now. Any assistance would be appreciated.

I think you can use inheritance, it’s an OOP concept applicable to blueprints. Just create a base blueprint with all the common components then you can right-click on it and choose create child blueprint class to create a new blueprint based off that. You can read more about it on the documentation at:

There are two main ways to bring order to your chaos:

  1. Inheritance, that you are actually already using. When you created a BP for an enemy you got a list of base classes. You probably selected Pawn or Character and your BP became a new subclass of it.

Instead create (for example) BP_Enemy for everything that is common among your enemies. Then create a new BP_Soldier and instead of choosing pawn/character select your BP_Enemy as base class. Voila, your soldier now got access to all the common functionality. You can go deeper and create BP_Sniper based on BP_Soldier.

  1. Composition, that you are also already using. Your BP got components for meshes, audio emitters and similar. You can create your own components with blueprints. For example BPC_Rifle, BP_Grenade and BPC_Jetpack. When building a new enemy, just add the components you need.

A combination of the two is usually best. Creating and using components can be more difficult, but allow for more flexibility. Too much reliance of inheritance can lead to problems if you invent an enemy that do not fit your inheritance tree, and changing the tree is often difficult.

I do not know much about AI in UE4, but this seems useful for how to handle it:
https://answers.unrealengine.com/questions/238875/subclassing-behavior-tree.html

1 Like

Yeah, this is basically a textbook example of a situation where object-oriented programming shines.
And, lucky you, blueprints are inherently object-oriented. The engine will aid you here.

When a class inherits from another, it can take the attributes of its parent class or overwrite those attributes. In this fashion, attributes that all children use equally can be changed by adjusting the parent, while child-specific attributes can be changed for the child only.

You can inherit multiple times if you want. So you start by making a general blueprint for enemies. Then you let the groups of enemies inherit from that blueprint. And then you let the actual enemies inherit from the group blueprints.

1 Like

You guys are brilliant :smiley: I’m still working on being brilliant hehehe

ok I have a BASE_AI…and literally all of the rest are a child of that but it doesn’t inherit any of the blueprint scripted stuff in the event graph from the base_ai…Whenever I change something in the event graph, none of those changes ever spread to the rest of them and this is what i want solved.

I don’t know how to turn a BP into a component…none of them have a weapon in the viewport or the components, they are given a BP of one upon spawning. I am about to add the third weapon type too, and if this goes well even a 4th.

You may not believe this but so far, I’ve written nothing down about this game. maybe its time to do so :smiley:

This may be a bit long (9 minutes about what got changed/added/fixed and then 1 full round of gameplay, but here is the latest video on it so you can sort of get an idea. It’s kinda of a rogue-like FPS survive as long as you can kinda thing, beat your high score…- YouTube
So you can visualize this, the tree of characters:
Group1 is TAN (weak enemy) blue bullets
Group2 is GRREEN (medium enemy) green bullets
special guy 1 white hair (Strong) white bullets
special guy 2 blonde hair (very strong) yellow bullets
special guy 3 Black hair (WTF strong) red bullets

The event graph is not inherited. It should not be used at all in a class designed to always be subclassed.

From a quick look at the graph in your video, you have some major refactoring (rewriting code while keeping the functionality the same) to do. PM me if you need hands on help.

ok I sent a PM to you

Event graphs are not inherited, but functions are. They don’t appear in the “functions” list, but can be called anyway.
Ever wondered why there’s an “override” button next to the “new function” button? That allows you to redo functions that were implemented by the parents.
I just tested giving a pawn a child and actually got this in the Event Graph:
Screenshot (104).png

It calls the parent’s version of this event, but I’m not sure about the specifics. Personally, I’ve only used inheritance for my guns and only as a really rough prototype. In my case, it’s basically a repository of functions like “reload” and “shoot” that are similar among children.
With a right-click, you can invoke “Add call to parent function” on any event that is implemented by the parent, to get another of those orange nodes.

And yeah, writing down is good. I have a bad habit of writing down the high-level stuff and then just doing the low-level stuff by trial and error.
This got really messy with my ammo system and UI and forced me to actually plan stuff out on paper.
When it comes to inheritance and stuff, it really helps to sit down with a sheet of paper and work out the details.

Your game looks pretty interesting, I’ll watch the video more closely later.

Does inheriting work for behavior trees, though?

And yes, you can call parent’s functions from the child. I have done it in my road tool blueprints, which all inherit from a common bp.

@vb4

All very complicated stuff to my pea brain. I have a problem with learning by reading. Hearing and seeing works far better. it’s like, if someone took one of my major blueprints and “cleaned it up”…I would be able to learn how to spread that through the project.
@Zirael no idea really there is a parenting functionality in BT’s but I have no clue how to use it.

Small hijack (mostly on topic).

I am making similar system (for guns). I used inheritance. However there is small problem, how do i trigger event from parent to inheriting child. In this case i want to propagate event “Shoot_Now” from parent.
I done it trough dispatchers (child hooks parents dispatcher), but there must be easier way. I just cannot figure out how to declare such event.

And another problem with inherited actors and blueprint animation this time. Each inheriting gun blueprint uses different skeletal mesh thus animation blueprint. My problem is that all of them (anim bps) do exactly same task, ie if player is shooting move trigger bone to some location if not move trigger bone to another location. So far i made code in each of those animation blueprints. Is there a way to avoid creating same graph 20 times?

Not sure if I understood this correctly, but you can override Events on children as if they were functions and optionally call parent’s version as vb4 mentioned above.
I keep *empty *CustomEvents in the parent, so I don’t have to *create *them on every inheriting child, sheer laziness.

I want parent to call its children event, so parent triggers child executes code. Thanks I will try your suggestion later today.

Back from what Havoc said…how do you turn a BP into a component?

my worries are not the general settings …and all of my characters are based on my base AI so i did something right…its just this problem with the darn ton of code in the event graphs…having to copy all the code and replace broken nodes in the whole things is a monster pain. the same will be for the AI stuff when I am done with this new one (starting over with AI basically…I seriously dread all the replication by hand of everything.

You create BLueprintable Component then copy your code there. Some extra code is required for component to communicate with owner.

That’s not how inheritance works.
The child always adds complexity on top of the parent. A child inherits from a parent and can call the parent’s function, because it’s the parent plus some more stuff.
The parent, meanwhile, knows nothing about its children.
The hierarchy always goes in one direction.

What exactly are you doing to get an Event Dispatcher working? Do you have a master-gun in the level that tells all other guns to shoot or what?
Forgive my dumb question, but are you aware of the difference between a blueprint and an instance of a blueprint? This sounds somewhat like a misunderstanding in regard to that.

@Everynone:

Actually, those empty custom events are standard procedure for object-oriented programming. There’s a thing called “virtual classes”, which are classes that list their functions and stuff, but don’t have anything inside. It’s then up to the children to actually add functionality by overriding everything. So an empty custom event, created for the sake of inheritance, would be a virtual event.
So you are being clever, not lazy.

Parent BPX_Weapon has all logic for shooting, it has all code for autofire, starting stopping, ammo counting etc.

Child blueprints for eg. BP_Colt_1911 only define visuals, location and vector of ejected shells. I want to have almost no code in child objects because if i have 20 guns it is same code times 20. But child blueprints should know when parent fires or that gun is out of ammo. I can read parents variables (but pooling is ugly), I also can hook to dispatchers, but there may be better more elegant way.

Every gun has its own class inherited from BPX_weapon, BPX_weapon is never placed in level. It is just used to store all code.

PS. I am also looking for solution to have all code in single place for 20 different animation blueprints. Code is essentially same, all i need to do is move single bone (trigger) in skeletal mesh when fire event starts and move it back when fire ends. But that trigger bone is in 20 different skeletal meshes.

PPS.
Creating event in parent class, then overwriting it in child works exactly how i wanted. So no need for dispatchers.

This all depends on the Instance you spawn.

If you have Weapon_Base with the Shooting logic and Weapon_A (Child of Weapon_Base) with the Models etc,
and you spawn Weapon_A to call “Shooting” on it, it will use the Parent code unless you override the function in that child.

If you have a Reference Variable of type “Weapon_Base”, you can store all Instances of Weapon_Base AND/OR it’s children into it.
If you save an instance of Weapon_A into it, you can only access the variables in it, if you cast it to Weapon_A. You can still call “Shooting”
on the Variable without casting (since the variable type is Weapon_Base) and it will STILL call the Parent OR Child implementation, based on the simple fact
of the Child overriding it or not.

You can also tell the Child to call the Parent code too. You can not tell a Parent to call child implementations.

So if you have the Function overridden in Weapon_A and you spawn a Weapon_Base, you can only call the Weapon_Base version of “Shooting”.

Does that answer your question?

I know object oriented programming, but for some reason i forgot (or did not realize) i can overwrite Events of parent class.
That overwritten event is exactly what i need. Parent does bulk of calculations, then calls that event. Event is executed inside child and uses calculated stuff to do something that depends only on child’s weapon type.