Announcement

Collapse
No announcement yet.

UFSM: Finite State Machine

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    That worked, the problem was that my VS 2019 was not setup correctly and was not vompiling the project... my bad sorry..

    I am getting this in the log?

    Exit: ]---------->(Standing) at (StateMachineComponent /Game/Maps/UEDPIE_0_TestLevel.TestLevel:PersistentLevel.BP_Player_C_0.Player Stance State Machine)

    Last edited by chiblue3d; 05-02-2020, 12:13 PM.

    Comment


      Hi, I bought this plugin a few years ago but just coming back to Unreal after developing my own FSM system in C#. I'm glad to see it's still being updated so I'm going to be using it for my project (no C++ unfortunately). I'm a little disheartened to see the documentation still very lacking beyond this thread and the API reference but it is what it is I guess.

      So I guess I'll just need to ask some questions instead, but apologies if they have already been asked.

      1. I'm not currently needing a ton of complex use from my FSM although that might change in the future. But one thing that I will be doing a lot is playing an animation montage within a state (let's say, PlayAnimation) and waiting for it to finish before switching states back again. I understand that if this was in an animation FSM I can just set the state when the transition ends, but since this is a montage and I want to play the montage from the OnBeingPlayAnimation, I have a variable set up that reads the montage length then, in the FSM event graph I'm doing a switch on the update and simply using a delay with this time before manually setting the state back to normal. This is pretty yucky to me and I can't imagine it's the preferred method, so is there some built in way I can do this? I can't use a delay within the OnUpdatePlayAnimation, and honestly that's still a bit dirty anyway.

      2. Would the general preferred method be to use both the FSM component as well as the AnimBP to control where the states go or try and keep it to the FSM component as much as possible for cleanliness?

      3. I would like to keep all my gameplay functionality contained within the states. So for example, when the user presses the jump button, if it's in the normal state it will jump, but if it's in a crouching state, it will stand (or whatever). I know I could get the current state and do a switch based on that, but that feels like it flies in the face of the FSM philosophy (moving away from enums and conditionals towards self contained code). However, we are only given begin, update, end and finish. How can I encapsulate more than that within a state such as events? This seems like a core piece of the puzzle to me to keeping state machines organised.

      I will undoubtedly have some more questions as I go down this rabbit hole, but if you could give me some advice on the best way to set this up I'd appreciate it

      -edit- I've switched it so in the OnUpdatePlayAnimation I'm checking the animbp if any montage is playing and when set to false I'm going back to the normal state. Again, unsure if this is the best way but seems much better than using a delay.
      Last edited by PlayingKarrde; 08-15-2020, 01:04 AM.

      Comment


        PlayingKarrde in a situation like this I prefere to have my AnimBP as a subclass of the AnimBP classes included with the FSM plugin, and on the FSM Component I setup "transition rule functions"...

        I will try to explain quickly what you need to setup transition rule functions for a FSM Component (not the anim bp):


        1) A enum to store states is good to have because then I don't need to type enum names anywhere or memorize state IDs; So I create a enum BP for the states needed before working on the component, like this sample one:




        2) I setup the FSM Component to actually use the enum BP as state input data, and make sure that "auto flow" options are enabled. I create a FSM Component Blueprint (FSM asset) for this, I do not use the native FSM component. With that checked, I click the "+Functions" button on details panel of the component, it will create state functions:




        3) Transition rules are functions prefixed with a "<T>" on their category. The ones I don't need later I just delete them:




        4) Transition functions will return a value to the c++ runtime of your FSM Component, depending on the value returned the component does the same thing an animation transition does, switches to target state; So you can use custom nodes included with the plugin to evaluate rules and dictate what a transition should return based on what you have just evaluated there. See some of the evaluation nodes here:




        5) So, you could setup a transition rule that will automatically quit your montage's state and go back to 'normal' state as soon blend time is where you need, instead of using Delay nodes;
        Something maybe like this:




        6) And because the AnimBP is child of the "FSM Anim" that is added with the plugin, and states on the FSM Component are input from an Enum BP... On Anim BP graphs it's possible to also modify behavior checking what the FSM Component side is doing with a simple Switch on (enum) node, I use this setup quite a lot, something like this:

        | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

        Comment


          Thanks for the reply and detailed response. Making the anim bp a child of your anim bp is a great idea and will no doubt save me some headaches later. The conditional transitions are also great to know about.

          How would you go about encapsulating functionality though? Basically what I'd like is to be able to have my states keep functionality for controls. So for example, in your blog post from a few years ago with the setting up a ladder example, you send the input axis to the FSM component so the states can read that as they like. I'd basically like something like that but for a button press. I don't want to have conditionals within my states or within my character BP since that starts to defeat the point of an FSM in that it can get complicated fast. I also would prefer to not have to set a bool then unset it again, as that too is messy.

          I'm sure what I'm asking is already possible but I can't think of the correct way to go about it.

          Comment


            You can have hierarchical state machine node graphs (HSM) within FSM Component graphs. They are great for handling controller inputs.

            ​​​​​​Latest demo project have an working example of them in use on character blueprint. You can find link to demo project on plugin's marketplace page.


            There's a little introductory info about them here:
            https://forums.unrealengine.com/unre...41#post1717741
            | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

            Comment


              Originally posted by BrUnO XaVIeR View Post
              You can have hierarchical state machine node graphs (HSM) within FSM Component graphs. They are great for handling controller inputs.

              ​​​​​​Latest demo project have an working example of them in use on character blueprint. You can find link to demo project on plugin's marketplace page.


              There's a little introductory info about them here:
              https://forums.unrealengine.com/unre...41#post1717741
              OK I'm still trying to get my head around this. In your example you have two example character controllers doing the same thing, but one is using an FSM and the other an RSM. I'm not really understanding how they can be used together (and why your example doesn't do so?). Should I be firing into the control RSM (using your example's terminology) in the FSM's begin state (say, Normal) and firing into the exit node on the end state? The way you have it seems counter-intuitive to me - two different systems not working together at all.

              I'm clearly failing to understand rather than it being a failing of your system (documentation!?). I like the idea of encapsulating states in state actions and plugging them in. But how the RSM fits into the state machine system I don't see still.

              -edit- Just for clarity, here's what I want to do:

              1. Have an input, say, Jump fire an event
              2. Each state has the ability to listen for that event and when it happens do some logic based on that
              3. None of this I want to happen with a case statement or any kind of bool checking - if the Normal state is active then the logic tied to the jump action fires, if I am in the crouch state I want the jump action specific to the crouch state to fire. Neither state needs to know anything about the other state and there shouldn't be any branches or switches anywhere.
              Last edited by PlayingKarrde; 08-26-2020, 11:27 PM.

              Comment


                In example project the "Input" BP goes towards that direction.

                The character BP only sets a state based on player input.
                Jump key will jump otherwise it will double jump depending on current active state, that's what I was referring to.
                | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                Comment


                  But you are setting a bool (DJump) in your double jump state and checking against it in your jump state and then unsetting it again on land. Having to keep track of bools being set and unset surely goes against the FSM philosophy no? All code should be compartmentalised and slotted in when in that state. Otherwise you end up with dependencies all over the place which is essentially spaghetti code once again.

                  Again, I'm prepared to admit I'm not understanding something here but I still don't get it.

                  Comment


                    The ONLY reason that boolean exists there is because the Animation Blueprint needs it, it's cheaper to check for the bool than the AnimBP query current state every frame:



                    That bool has zero effect on state logic in the RSM graph.
                    | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                    Comment


                      OK, I'm sorry if I'm coming off as obtuse but you're not really helping me understand how RSMs are working with FSMs in any way. Your FSM system makes sense in that, what state an FSM is in is what is active. Typical FSM stuff - great. But the RSM seems to have all it's "states" running concurrent and so the state machine isn't really active at all. Your character controller is just sending input information to your RSM. You say the logic isn't controlled at all but isn't this logic for jumping? Anyway I don't want to get caught up on that... My question is really about trying to understand how RSMs fit into the equation because how I'm looking at it, it doesn't look like there's a state machine going on here at all? FSMs yes, but the RSM is just all the states running at once?

                      Again, sorry if I'm coming off as terse or rude but I just don't get it...
                      Attached Files

                      Comment


                        That's an "Action" graph. Maybe you are confusing actions with states?!
                        In RSM node the state is the node itself, it is a "reactive system".

                        Actions are executed as a queue, until you call an exit point, getting the "flow graph" to move to next state/node graph.
                        For example, "Aim" in this case is its own state and while it is active, player will not be able to jump because there's no "Jump Action" in its action list:

                        | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                        Comment


                          OK that's interesting. Yes you're right I was confusing actions with states. I'll dig into this a bit more tomorrow but this is promising. Thanks.

                          Comment


                            Keep in mind that you can create FSM blueprints and add these "RSM" nodes to the FSM graphs as well.
                            | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                            Comment


                              Ok I *think* that's probably exactly what I'm after. One thing I'm a little stuck on is creating these nodes. I'm choosing New Reactive State Machine and setting the machine class to my RSM Input that I created. This, however, doesn't produce an RSM Input FSM object reference, it instead (probably obviously) creates a Reactive State Machine. What am I missing here?

                              Comment


                                If you see in demo project, there's action base classes in asset browser.
                                You can right click asset browser and create as many more "Action" classes as you want.
                                It's a bit confusing at first, but everyone soon enough understands the usage pattern:











                                When you add a node to a graph, you can define the node's RSM base class + add there in its details panel the action classes you want the node/state to execute (edit: select the RSM node and go to its details panel):









                                ** Then you have to recompile the blueprint once you've made changes a RSM node.
                                ** Also always define unique "Machine Name" for each of your RSM nodes.
                                ** I do not recommend using the "Machine Class" for multiple instances of same Character class, because your brain might have trouble tracking execution flow for each, I'd rather use 1 machine class for 1 specific graph to save my sanity..

                                And then you can code "Action" graphs as if their were little pieces of logic regardless of who is the actual Actor these actions are running on.
                                Once you have a library of actions, you can share them among any RSM node you might see need some specific actions.
                                Last edited by BrUnO XaVIeR; 08-27-2020, 03:42 AM.
                                | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                                Comment

                                Working...
                                X