GC FSM - Event-driven, hierarchical finite state machines in blueprint

Version 1.1 of GC FSM is now available

Actually, version 1.7.7 of GC FSM went online just yesterday.

Hello,
I’m coming here for a design problem and I was wondering if you already encountered that problem before and know how to solve it.

Here is what my FSM looks like right now:
[0_fsm_is_opened.PNG]

What I want, as shown on the screen, is to avoid having to trigger BOTH “IsOpened” and “Battle|Call|Map|Alert” events to actually go into one of the OpenedFSM states.

I have found something that works, but I’m not sure it’s the best way to handle this.
I’ll demonstrate it for the Opened_Battle state only, as it works the same for the other ones.

I added a FName ExitEvent variable to my FSM, and changed the “IsOpened” transition to “Battle” for the demo:
[1_fsm_battle.PNG]

In BP_ADFSMS_Closed, OnExit, I’m now setting that ExitEvent variable:
[2_state_closed.PNG]

In BP_ADFSMS_Opened_Idle, OnEnter, I trigger the event a second time using that variable. Then I reset the variable.
[3_state_opened_idle.PNG]

It works: I now just have to trigger the event “Battle” to do Closed->Opened->Battle in one shot.

Do you have a better idea?
Thanks for the great plugin anyway! :slight_smile:

Can you do something like this?

Hi @DsyD ,
Thanks for your suggestion :slight_smile:
However, that would not be very convenient as we will adding Event pins to the OpenedFSM.
As you can see in the first screenshot I’ve attached, we already have an additional “End Match” pin that leads to a FSM Stop node.
That would force us to add an “End Match” pin to every Opened State (Battle, Call, Map, Alert), and do the same every time we will add a pin to the global OpenedFSM.
This is not very maintainable, I’m afraid!

Hi @raboulave, yours is a very interesting example. Your approach definitely works. I agree that it’s a bit cumbersome to have to save the event in a variable to re-trigger it in the submachine. It would be nicer to have a way to “inject” a past event into a new submachine state, but unfortunately that’s not currently supported. Good food for thought, though. BTW, why do you need to cast the context variabile? You should be able to just declare the variable of the correct type. Unless you are going to re-use the state class for different classes, in which case you are probably using a base class…

FSM is great, however those returning pins and wires (from right side of graph to the left) are real pita. Something should be done about this.

Thanks @gamecentric for your answer :slight_smile: We’ll keep that way of dealing with re-triggering events then, until eventually you come up with something fancier.
As for the cast, this is simply because the ExitEvent variable was on the BP but the Context variable is of a custom FSM base class and is declared in C++, but thanks for having looked at it so carefully!

I see, I didn’t know you wanted to have more than those four “Opened” sub-states. In that case I think it makes sense to have Opened and Closed states.

Is it the case that when “Opened,” every sub-state (Battle/Call/Map/Alert etc.) is reachable from every other sub-state? In that case, it might be easier to just store the sub-state as a variable, like an enum. In a typical (deterministic) FSM, the next state depends on the input and the current state, but if every state can be reached from every other state, then the next state only depends on the input. So you only need to observe the input to determine what actions (side-effects like OnEnter) to execute.

Thanks, that’s another good suggestion.
We won’t use that now though, since the project is in a very WIP state and we still don’t know how that object will be used.

Just an idea: you could use internal events to catch the Battle, Call, Map, Alert in the Closed state. In their respective handlers, you trigger the IsOpen event and also re-trigger the original event, in this order. When an event causes a transition, all subsequent events will be handled in the next tick and this should give the Closed FSM time to handle them. Didn’t have time to try it…

Oh, sorry, I had not seen your message!
If you mean something like this, unfortunately that doesn’t seem to work :frowning:
Both “Trigger FSM Event” nodes are called before entering the IsOpened sub-FSM.

Sorry to have kept you waiting. I just submitted to Epic a version of GC FSM supporting Unreal Engine 4.26. I’ll post here when it’s approved.

Aaand it online. Enjoy!

Hey,

Is there a reason why there is no “Stop FSM” node available? Not “FSM Stop” that is used by the FSM, but a node similar to “Launch FSM” that can be used to stop a specific FSM. That is, stop the FSM and release resources associated with it.

Sometimes you have a state machine you simply just want to reset or stop, for various reasons.

Hi [USER=“1210893”][/USER] you can mimick a similar behaviour by making your FSM a sub-FSM of a higher-order FSM using a submachine state. Then, by triggering an event in the high-order FSM you can exit the submachine state, effectively stopping your original FSM. By re-entering the state, you can also implement resetting. Hope it helps.

That works perfectly, thanks!

Hi, I’m happy to announce that a version of GC FSM targetting UE 4.27 is now available on the marketplace.
Enjoy!

Can state machine cause delays?

I have build my whole project, from player movement (Moving on ground, dashing, sliding as separate state machines) to anything i need logic only on a specific condition as a state machine and now i’m getting input delays. Not frame drops, as my scene capture updates just fine, but instead as if all input, (Fsm event and direct binding to an event) gets queued up and slowly executed. I have ryzen 5 so it can’t be cpu

Can someone explain me WTF is this ■■■■ bug? I need to do this ■■■■ fix every single time i restart the editor