Managing Multiple Mechanics?

Hi all! Right now, I’m working on a classic feel 3D platformer, that has a handful of platforming mechanics and abilities. Naturally, you wouldn’t want to use one mechanic at the same time as the other. For instance, if gliding in the air is controlled by holding the left shift while in the air, but ground pound is used when in the air and pressing another key, how could I differentiate the two actions? Now, the simple answer (and what I already programmed) is to just set up some conditions to make them work independently, which was fine until I started to throw in other mechanics. Like, if I’m gliding, I’ll have to cut off jump, double jump, and mechanic number 3, but when I ground pound while gliding, I’ll have to cut off gliding, but maybe mechanic #3 becomes available, and jump and double jump won’t turn back on until I land. It get messy, you see? And right now, I have a web of booleans that has gotten hard even for me to keep track of.

My programming teacher always said, “Code smarter, not harder”. It sounds like a stupid question, but is there perhaps a simpler way to organize or implement small abilities without having to get a hundred bool variables and endless if, and, or statements. (Right now, abilities the player can use independently are all under the same character BP)

Take look at CGFSM plugin, it is great for what you want to do.
But it is code plugin so if your platformer is made for mobiles, iti is more trouble (to use code plugin) than it is worth.
Anyway you can create prototype (using this plugin) then create all states and functionality in blueprints if needed.

You also can place all that logic inside animation blueprint, use state machine there to drive animations. Add anim notifiers to anims and send information back to player pawn about state of animation and player. But this approach is kind of messy, if you canage animation and forget to add notifier your game code suddenly stops working.

I wish epic just did native finite states machines like that plugin (code is there, it is just not exposed for general BPs, only for anim state machines and blackboards in ai).

Edit there is moar:
You can also create additional child (inheritied) character blueprints.
I split mine into layers: locomotion and animation, game mechanics like inventory weapon handling etc, and pure cosmetic (look) layer. So i have 3 player character blueprints each with different focus.

Then i use (everywhere i can) blueprintable components. Each component handles some tiny aspect of game.
For eg i have components for eyes and head, that track target and calculate all angles for animation blueprint.
Then each weapon socket has different blueprintable component that handles events like equip/unequip for swapping weapons and attaching them to holster or hands.
Then 2 components of feet that calculate distance to ground, what material player is on, and wait for anim notifier to fire up and tell them to play sound at location.

So all code (whatever i can) is split to smaller containers that are autonomous.

That’s pretty neat! Is there a link to doing something specific like that? I believe I read somewhere before, where someone had abilities as components, but that related to weapons and spells, not sure how you’ll go about creating mechanic/ability components. But something like that could definitely work! At least, to make the blueprints not look so complex, I had it to where major locomotion and movement were in the event graph, Camera Controls were in another event graph, and abilities were in another. Other small specifics like turning things on and off and changing the player’s “state” was handled using bools and functions, which got crazy. If I just extend the inherited character blueprint to another, how would that be any different from creating another blank page of an event graph?

I’m trying to create an Actor Component and attach it to the Character Blueprint to replicate a simple jump, but I can’t seem to get the jump input to come up. Is there a way to create a component specifically for a character? That way I can receive inputs?

What I imagine with this method, it that I’ll be able to add or remove components to turn on/off abilities while other abilities are in use, instead of having so many bools and conditions to check.

Ugh, after hours of trying, I have no idea of what the hell I’m doing and I’m about to give up and kill myself…I’m able to add components using AddComponent node, and I put some jump logic in there, but it’s no different than what I already have; just putting parts of the code somewhere else with all kinds of bools and checks. And some of it doesn’t even work! How can I just add or remove components if I’m using another ability or not?

I really need some help guys, it’s killing me!

This is not easy stuff, you need work more on blueprint to blueprint communication.
I would suggest starting with dispatchers and bluprint interfaces (not umg , but function interface).

You create all needed events in parent character pawn. Each event there should fire up animation or move char etc. Leave logic of what can be done at any given time to either child (inherited) blueprint or components.
With blueprintable components you do similiar, create parent component that has all code to communicate, the ninherit child components and code there each ability. Let them check what state their owner (player character pawn) has. Then put logic of what can be done inside blueprintable component, it should decide if ability can be used or not. If ability can be used and player (person wants to use) that component should send event back to player pawn.

This way when you make single ability and it works you can just add or remove that component from player pawn.

And use blueprint interfaces (again coding ones, not umg) those can be called inside arbitrary classes that implement them, so no need for class checking casting etc. You just trigger interface call message.

And keep trying, more you learn now (at beginning of project) less trouble you will have when it grows.

Also receive all inputs in single blueprint (at some poit you want make custom keyboard bindings) it is better to have such stuff together.
Create event dispatchers, and custom events inside other blueprints. Get input in player character, then call custom event in another blueprint.

Yeah, that is some work, I’ve messed with blueprints a lot but this might put me to the test. I’ll see if I can try and find some examples, I’m still kinda lost…I’ll play around with this and see where I can get and report back.

After playing around with it a bit more, I went ahead and created an Actor Component that will always be attached to the player. This is my “Parent” component or Mechanics Component, if you will. Adding components to the Parent seems to work, but you were right about casting. I.E. if I added the Jump Component with all the jumping logic to it, and tried to use it in the Character Blueprint, I would have to do a bunch of casting which is quite annoying.

So instead, I went the next route and kept the Parent Component on the Character, and used an Interface within the parent for the Jump (each mechanic would be an interface, is the idea). Within the small network of the jump logic, I went ahead and created a second boolean. (I have two booleans for MOST mechanics, one is to turn on the mechanic, similar to buying a new power at a certain level in the game, which is kept in the Character blueprint, and two is to toggle it on or off when other mechanics are in use) This boolean is out of sight, right in the interface. If I want to turn it on or off depending on other mechanics, sure, I’ll have to cast within that interface. But that’s something I’ll have to look into soon, like could interfaces cast or communicate with other interfaces?

As of now, all I have to do is grab the reference of the Parent in the Character BP, and call the Jump Message to get it working. I’m not quite sure, though, if this would work for other skills or if this is even productive to what I was trying to accomplish above. Any advice will suffice. Thank you!

Welp, none of that crap worked, back to square one…