How to override states in state machine? (SOLVED)

Greetings,

In my prototype I’m making, I’m testing out a finite state machine that works with a transformation system. In my game, you can collect items to temporarily transform yourself with new abilities.

So I have a basic FSM set up here:

So far so good. So when my character collects a cake, I want them to transform, changing into a state that acts as the “transition” to the transformed state (Plays an animation).

However, when I touch the cake, nothing happens. I even have debug text showing that displays the state, and it’s not changing to “getsugar.” My current states are overriding this state…

I tried using Trigger Onces and a scene variable to block them, but they introduce their own issues. I COULD just use a “Variable is NOT getsugar” for each state, but it’s a bad practice, and with a lot of transformations, that can get messy…

I did that with an old project back when I was still new to this engine, and it got messy and out of control fast:

VERY OLD CODE:

So basically, what’s the best way to override my basic states and force a new state to start (You know, without making my code look like… THAT ^^^^^)?

Here’s how my state machine works so far if it helps:

Is the way I have my state machine set up currently too much? Should I simplify it?

Help is appreciated, thankuuu

The problem is the way you’ve implemented the FSM. As it stands, you’re waiting for an animation to finish, but only if the state is “getsugar”. The state will be changing while the animation is playing, so the final getsugar event will never get actioned.

The idea of an FSM is that you code all the possible actions for each state. You have a parent event that checks what the state is, and then have all that state’s events as subevents. It might mean some actions are repeated in multiple states (so checking for idle will be an separate event for each state that needs it), but it also isolates the actions for each state to only e run while in that state.

This bit here is an example:

That first event is checked no matter what the state is, and so will get checked for every state.

Ideally you’d have

State is Idle
    idle event1
    idle event2
    idle event3 etc

State is jumping
    jump event1
    jump event2
    jump event3 etc

and so on.

You won’t need to check if the player is idle when the state is idle. Nor will you need to check that the player is idle or jumping while the state is getsugar and the animation hasn’t finished.

Refactor the events so each state has it’s own set of events, and you should find it works.

1 Like

Hmmm, you mean like this?

I’m checking out the Not-A-Vania example for pointers. While it DOES work, and works well, it looks like an awful lot of code to copy paste. Despite that, I appreciate how much control you have over it this way.

Is this truly the most ideal way to make the state machine?

Not quite, because “playerhitbox is on floor” is not a state. And because that very first event is not part of a state either.

Something like:
image

Each of those events is the parent of other events that only need to be processed when the player is in each specific state.

1 Like

Ohhh, I think I see now!

I rearranged my events to match this more, but I’ve run into another issue

Specifically, transition to idle

I tried to make it so that if the player is not moving, change to idle, and now I’m currently using if none of the movement keys are down

Neither works. The player just scoots one pixel across the floor when I press the move key and the state stays in idle

I have no idea why this doesn’t work, considering Not-A-Vania does this same sort of thing and it works just fine

The online FSM documentation says to use an inverted “Any key pressed,” which DOES work, but that could cause bugs, as if I’m holding another key down, the state stays in move, which could cause problems down the line. Basically, I’d like to narrow down which keys have to be not pressed

Is there something I could to do fix this?

I think the problem is with this:

image

I’d suggest you get rid of the inverted “If one of these conditions is true”, and just have all 4 key pressed checks inverted.

And get rid of the trigger once conditions if the actions change the state, because the event won’t be processed again for a while.


And if that doesn’t fix things, then it could be that the state is being changed to idle elsewhere.

1 Like

Excellent, works like a charm now. Thanks!

I’ll keep tinkering with the state machine and see if I could get the transformations to work now

1 Like