Announcement

Collapse
No announcement yet.

UFSM: Finite State Machine

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

    Originally posted by BrUnO XaVIeR View Post
    It is done this way because AnimBP syncing.
    Since you apparently aren`t using that sync, I believe you can remove that logic from BeginPlay and place it where it fits your code:
    Code:
    FSM_Transition Transition;
    MakeStates(STATES,Transition);
    
    InitializeFSM();
    You can call that sequence anywhere needed. It's placed there in BeginPlay because, again, AnimBP State syncing.
    Thank you so much! Working all round now.

    As a heads up or for anyone reading over this, the code you provided here wasn't resetting the state time, and I don't need to replicate that since the state itself is being replicated so:

    Code:
    void UStateMachineComponent::OnREP_StateID_Implementation(uint8 &ID)
    {
        ID = StateID;
    
        FSM_Transition Transition = FSM_Transition::Succeeded;
        Exit(PreviousStateID, ID, Transition, InExit);
        Enter(ID, InBegin);
        StateTime = 0.f;
    
        if (Transition != FSM_Transition::Succeeded)
        {
            LOG_PIE(Debug, ESeverity::Warning, this, FFIND(TEXT("OnREP_StateID")), FString("[OnREP_StateID]: Exiting 'PreviousStateID' was aborted."));
        }
    }

    Comment


      I finally got the plugin update installed.

      I'm getting a new issue - the startup state is being ignored and it's just using the first state in the enum.

      If I force the state on BeginPlay it returns "unchecked". What does this result actually mean? There's nothing in the output panel.

      Comment


        It just means it wasn't checked to exist or not.
        This "Unchecked" thing is there because there's people adding/removing replicated States at game runtime...

        But it shouldn't do that for the startup, I will look tomorrow to see that is happening.
        | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

        Comment


          Originally posted by Antidamage View Post
          I finally got the plugin update installed.

          I'm getting a new issue - the startup state is being ignored and it's just using the first state in the enum.

          If I force the state on BeginPlay it returns "unchecked". What does this result actually mean? There's nothing in the output panel.
          I can't reproduce what you report.
          Did you try clean up the "FSM States" array and input your Enum BP again?

          Every time here the startup State is what set it to be...
          | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

          Comment


            Originally posted by BrUnO XaVIeR View Post
            It just means it wasn't checked to exist or not.
            This "Unchecked" thing is there because there's people adding/removing replicated States at game runtime...

            But it shouldn't do that for the startup, I will look tomorrow to see that is happening.
            Would there be other people or replication in a non-multiplayer game?

            Oh, got it. Somehow component auto-activate was unchecked. Probably from the plugin being disabled.

            Back to the original issue:

            Code:
            PIE: Warning: {FSM}:: 'Set State' named [EAIState::NewEnumerator9]: State ID doesn't exist. -->  FSM: Set State: [Function /Script/UFSM.StateMachineComponent:SetState at (StateMachineComponent /Game/AvGaHo/Maps/UEDPIE_0_Map_Bull.Map_Bull:PersistentLevel.PC_Bull_2.StateMachine)]
            FSMs: Warning: [StateMachine]: 'Set State' named [EAIState::NewEnumerator9]: State ID doesn't exist.
            This is weird. My enum name isn't "NewEnumerator9" and the type is right. I guess I'll just store it as a name instead.

            Comment


              Hmm...
              Are you comparing States to enum names??
              Unreal internally names BP Enums like that: "enum::itemname".

              I wouldn't compare States to bp enum names, weird things like that might happen; I'd only use them to "copy" States quickly into the States array, specially because the way Epic serializes BP Enums into assets (they aren't real enums).

              If you're getting the "name" of a BP Enum item it will output something like that (the internal name of item) instead of the display name you see in Blueprint Graphs.
              | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

              Comment


                I just had a typed variable for the state and I was setting it with a dropdown. Then when I was setting the state it was converting it into a name, so yeah probably. Normally that conversion works but I guess there's a UE limitation in there.

                Comment


                  Originally posted by Vaei View Post
                  As a heads up or for anyone reading over this, the code you provided here wasn't resetting the state time, and I don't need to replicate that since the state itself is being replicated so:

                  Code:
                  void UStateMachineComponent::OnREP_StateID_Implementation(uint8 &ID)
                  {
                      ID = StateID;
                  
                      FSM_Transition Transition = FSM_Transition::Succeeded;
                      Exit(PreviousStateID, ID, Transition, InExit);
                      Enter(ID, InBegin);
                      StateTime = 0.f;
                  
                      if (Transition != FSM_Transition::Succeeded)
                      {
                          LOG_PIE(Debug, ESeverity::Warning, this, FFIND(TEXT("OnREP_StateID")), FString("[OnREP_StateID]: Exiting 'PreviousStateID' was aborted."));
                      }
                  }

                  Good practice would be also check if it actually replicates, like:
                  Code:
                  if ( !ReplicateStateTime ) {  StateTime = 0.f;  }
                  | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                  Comment


                    This occurred again. Last time the only way I could fix it was by rebuilding the state machine from scratch (which isn't happening so I need a solution). Somewhere it has corrupted. I try to delete it and remake the specific state but the issue persists. Now whenever the state is set to 1 it crashes.

                    Comment


                      State object in TMap index 1 for some reason is null.
                      How are you creating States list?
                      Somewhere in the process index 1 is ignored when you create them.

                      _____

                      Btw, you can force State creation with:
                      Code:
                      StateMachine->AddState(1,FName("stateName"));
                      But I'd rather examine Blueprints and identify why this one in particular isn't being created in your setup...

                      You may have duplicate State names or related issue; now that TSet is supported by Blueprints I should convert name list from Array to Set, but that deprecation process is annoying so I may only do that for 2.0+ version on Unreal 4.20+.
                      ​​​​​
                      Last edited by BrUnO XaVIeR; 07-02-2018, 05:13 PM.
                      | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                      Comment


                        Originally posted by BrUnO XaVIeR View Post
                        State object in TMap index 1 for some reason is null.
                        How are you creating States list?
                        Somewhere in the process index 1 is ignored when you create them.

                        _____

                        Btw, you can force State creation with:
                        Code:
                        StateMachine->AddState(1,FName("stateName"));
                        But I'd rather examine Blueprints and identify why this one in particular isn't being created in your setup...

                        You may have duplicate State names or related issue; now that TSet is supported by Blueprints I should convert name list from Array to Set, but that deprecation process is annoying so I may only do that for 2.0+ version on Unreal 4.20+.
                        ​​​​​
                        I could construct an exact duplicate of this state machine from scratch and it will work. That's how I fixed it last time. Feels like something is corrupting internally.

                        I'm creating the states by simply adding to the array. I made an enum and provided that instead but no difference.





                        On an unrelated note since you mention 2.0 can I make a suggestion/request?

                        In the screenshot provided for the issue, you can see that some states are actually transitions, eg. "Equipped" is a state and "Equipping" is a transition; during "Equipping" state there is an animation playing, a sound, a material effect and when the duration expires it goes to Equipped.

                        And then the "FSM Default Links" already has a state that it transitions to when Finish State is called. For transitions that can go one way or the other, they'd need a BlueprintNativeEvent that takes the next state as an argument.

                        So basically, the idea is that the FSM Default Links could also have a 'Duration' set, when the Duration expires it transitions to the NextState. Furthermore, these could have a BlueprintImplementableEvent (or native if needed) that return the next state to transition to - so for example my "PickingUp" state is a transition that either goes to "Equipping" (if it can be equipped and nothing is equipped there) or "Unequipped" (in inventory), in which case I'd check it's destination in that function and return the "Equipping" or "Unequipped" state based on that.

                        If this does happen, it might be worth having an interrupted call back, if finish state or begin state was called part way through a transition. Also, when starting a state or transition from an interrupted transition it could be worth having the left-over time.
                        Last edited by Vaei; 07-04-2018, 01:50 AM.

                        Comment


                          What I can do easily, without breaking anything, is implement "latent" versions of "Finish State" BP Node which is used already to invoke Default Transition...

                          These nodes can implement the components you mention be needed, timers, callbacks, etc.
                          With a combination of properties above to a conditional check, Fsm goes to either State A or B... With a callback to either Event A or Event B.

                          It's doable, I will add this to todo list.
                          The small annoyance is these nodes are more friendly to Blueprint FSMs and not so much to pure Cpp Components, but will cover the issues well enough.
                          ​​​​​
                          | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                          Comment


                            Originally posted by BrUnO XaVIeR View Post
                            What I can do easily, without breaking anything, is implement "latent" versions of "Finish State" BP Node which is used already to invoke Default Transition...

                            These nodes can implement the components you mention be needed, timers, callbacks, etc.
                            With a combination of properties above to a conditional check, Fsm goes to either State A or B... With a callback to either Event A or Event B.

                            It's doable, I will add this to todo list.
                            The small annoyance is these nodes are more friendly to Blueprint FSMs and not so much to pure Cpp Components, but will cover the issues well enough.
                            ​​​​​
                            Sounds good! I don't see myself using it much in C++ anywho, but that's just me.

                            Any thoughts on how to fix that corrupt(?) state?

                            Comment


                              You can loop through the TMap container of States and check for validation... If any is null/invalid create a new State struct and assign to that index.
                              | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                              Comment


                                Originally posted by Vaei View Post
                                This occurred again. Last time the only way I could fix it was by rebuilding the state machine from scratch (which isn't happening so I need a solution). Somewhere it has corrupted. I try to delete it and remake the specific state but the issue persists. Now whenever the state is set to 1 it crashes.


                                Btw, whenever you change your Array of 'FName' States, add/remove/replace, etc... Make sure you call the "MakeStates()" function.
                                There is where State objects are generated and stored in the TMap.
                                You can also force the TMap to create a new State object in the problematic index:
                                Code:
                                STATE.Add(1,TEXT("stateName"));

                                _____
                                Edit:

                                Actually what seems to be invalid is the "Name" variable of your State object in index 1.
                                If was the object struct it would've crashed earlier, not in that line.
                                Last edited by BrUnO XaVIeR; 07-04-2018, 07:53 PM.
                                | Savior | USQLite | FSM | Object Pool | Sound Occlusion | Property Transfer | Magic Nodes | MORE |

                                Comment

                                Working...
                                X