playMaker

Author Topic: SetState before enable [SOLVED]  (Read 2174 times)

Amitloaf

  • Playmaker Newbie
  • *
  • Posts: 9
SetState before enable [SOLVED]
« on: June 08, 2020, 02:38:16 AM »
I want to "load" the state of an FSM. For this I save the name of the State and then when I "Load", I just use fsm.SetState(name). The thing is, this only works if the fsm is active. So when I turn it on, it runs the first state immediately and only then I SetState to the new one. Is there a way to set which state it should start on when it's enabled?
« Last Edit: June 21, 2020, 05:15:36 AM by Amitloaf »

Thore

  • Sr. Member
  • ****
  • Posts: 480
Re: SetState before enable
« Reply #1 on: June 08, 2020, 05:36:32 AM »
Set the start state to a new state that is empty. Then you can always enter into it. Then, use your method to set what you want, including the “old start” state. You can also set a bool, in the new start state that checks whether it should go to “old start”, etc.

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 773
Re: SetState before enable
« Reply #2 on: June 08, 2020, 06:59:07 AM »
Quote
The thing is, this only works if the fsm is active.
So when I turn it on, it runs the first state immediately and only then I SetState to the new one.

Perhaps because you try to do the change and activation at the same time?
I did a quick test with either activating the FSM or its hosting Game Object after changing the starting state, there is no problem.
The "after" in this case being achieved either using the Wait action or a Next Frame Event for example.
It is absolutely possible to change the starting state of a FSM when it's disabled itself or when its Game Object is inactive.

On the lower left side of the Graph View, click on Debug and Show State Loop Counts and go to the FSM where the change must happen. You'll see that if you did things properly, the old state never gets triggered before the change (loop value: 0) whereas the new state does get triggered (loop value: 1).

Amitloaf

  • Playmaker Newbie
  • *
  • Posts: 9
Re: SetState before enable
« Reply #3 on: June 08, 2020, 11:07:38 AM »
Quote
The thing is, this only works if the fsm is active.
So when I turn it on, it runs the first state immediately and only then I SetState to the new one.

Perhaps because you try to do the change and activation at the same time?
I did a quick test with either activating the FSM or its hosting Game Object after changing the starting state, there is no problem.
The "after" in this case being achieved either using the Wait action or a Next Frame Event for example.
It is absolutely possible to change the starting state of a FSM when it's disabled itself or when its Game Object is inactive.

On the lower left side of the Graph View, click on Debug and Show State Loop Counts and go to the FSM where the change must happen. You'll see that if you did things properly, the old state never gets triggered before the change (loop value: 0) whereas the new state does get triggered (loop value: 1).

Really? I'm pretty sure I checked it and changing it while it's disabled doesn't do anything. I'll re-check - it could solve it.

Can you explain what is the loop value and loop count? It counts how many updates happen on each state?

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7616
    • jinxtergames
Re: SetState before enable
« Reply #4 on: June 08, 2020, 04:51:16 PM »
Hi.
When a fsm is Enable normally it will always start on the Start State.
But if you uncheck 'Reset On Disable' on the FSM Component it might work (never tried it tho)

But Thore's solution is safer.

I have many fsms with a empty start state and nothing connected, and use a event or set state to start doing what i want in that fsm.

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 773
Re: SetState before enable
« Reply #5 on: June 09, 2020, 09:16:09 AM »
Really? I'm pretty sure I checked it and changing it while it's disabled doesn't do anything. I'll re-check - it could solve it.

I created a quick test for that, a parent with a sibling, the parent is active on launch, not the child. Child has two states, 1 and 2, with 1 being the starting one.
The parent changes the starting state of the sibling from 1 to 2, then activates it. I haven't observed any issue there.

Check if the Game Object and/or the FSM is inactive so that it does not start before being modified and then told to start.

Quote
Can you explain what is the loop value and loop count? It counts how many updates happen on each state?

It shows how many time the flow passed through states. It's a bit arcane in that it shows 0 and 1, when a state's loop count has a value superior to 0, you know the flow went through it.
But then the number won't go above 1 unless the state is built in such a way so as to be part of a loop wherein the flow passes through this state multiple times during the same frame.
What I mean is that, unfortunately, it won't go to 1, 2, 3, 4, etc. if the flow passes through it during separate frames. I wish it would though, it would be very useful. See my feature request here.

For example, if you badly code your FSM and generate an infinite loop (keeps flowing through the same states within the same frame, never able to move to the next frame), you'll see the counter reach 1000 and you'll get an error.
« Last Edit: June 09, 2020, 09:19:51 AM by Broken Stylus »

Amitloaf

  • Playmaker Newbie
  • *
  • Posts: 9
Re: SetState before enable
« Reply #6 on: June 10, 2020, 06:47:22 AM »
Ok so Thore's solution is the one I thought of. But I already have thousands of FSMs already in the game. I can add it automatically to all of them but it might cause unforeseen issues so changing the State before might be a better fit for me.

Ok so I understand why it thought you can't set the state ahead and it's because I had Reset On Disable turned on (can I turn this off by default when creating a new FSM? Also, why does Reset On Disable resets on Enable?)

Now only problem I have is that when using SetState - even if the object is disabled, it actually runs it but as the object is not enabled, it can't receive events so if the event ends with FINISHED or SendEvent on itself it will just not happen and stay stuck like this when I turn it on.
So this kinda nullifies what BrokenStylus said :\ I need the state to actually run properly when I turn the FSM back on.

I guess I'll have to do the empty state trick then...
« Last Edit: June 11, 2020, 12:47:37 PM by Amitloaf »

Broken Stylus

  • Beta Group
  • Hero Member
  • *
  • Posts: 773
Re: SetState before enable
« Reply #7 on: June 12, 2020, 06:53:55 AM »
Ok so Thore's solution is the one I thought of. But I already have thousands of FSMs already in the game. I can add it automatically to all of them but it might cause unforeseen issues so changing the State before might be a better fit for me.

At this point you might want to use FSM templates. You can even point to a template when creating a new FSM by going in the FSM tab (1st of four tabs) and selecting the wanted template.

Quote
Ok so I understand why it thought you can't set the state ahead and it's because I had Reset On Disable turned on (can I turn this off by default when creating a new FSM? Also, why does Reset On Disable resets on Enable?)

Instead of activating this (or any other) FSM on and off many times, wouldn't you save the values in some hash table or array list once?

Quote
Now only problem I have is that when using SetState - even if the object is disabled, it actually runs it

May you clarify this please?

Quote
but as the object is not enabled, it can't receive events so if the event ends with FINISHED or SendEvent on itself it will just not happen and stay stuck like this when I turn it on.

I think a picture might help because I don't understand what you mean by an event that ends with FINISHED, which is a default system event.

Quote
So this kinda nullifies what BrokenStylus said :\ I need the state to actually run properly when I turn the FSM back on.

I guess I'll have to do the empty state trick then...

The empty state is something that gets often used in PM but I have the feeling that your system might be slightly over-engineered.
Maybe instead of swapping the START event around, you could have several FSMs on the same object?

Amitloaf

  • Playmaker Newbie
  • *
  • Posts: 9
Re: SetState before enable
« Reply #8 on: June 21, 2020, 05:15:13 AM »
Ok so Thore's solution is the one I thought of. But I already have thousands of FSMs already in the game. I can add it automatically to all of them but it might cause unforeseen issues so changing the State before might be a better fit for me.

At this point you might want to use FSM templates. You can even point to a template when creating a new FSM by going in the FSM tab (1st of four tabs) and selecting the wanted template.

Quote
Ok so I understand why it thought you can't set the state ahead and it's because I had Reset On Disable turned on (can I turn this off by default when creating a new FSM? Also, why does Reset On Disable resets on Enable?)

Instead of activating this (or any other) FSM on and off many times, wouldn't you save the values in some hash table or array list once?

Quote
Now only problem I have is that when using SetState - even if the object is disabled, it actually runs it

May you clarify this please?

Quote
but as the object is not enabled, it can't receive events so if the event ends with FINISHED or SendEvent on itself it will just not happen and stay stuck like this when I turn it on.

I think a picture might help because I don't understand what you mean by an event that ends with FINISHED, which is a default system event.

Quote
So this kinda nullifies what BrokenStylus said :\ I need the state to actually run properly when I turn the FSM back on.

I guess I'll have to do the empty state trick then...

The empty state is something that gets often used in PM but I have the feeling that your system might be slightly over-engineered.
Maybe instead of swapping the START event around, you could have several FSMs on the same object?

Well, When you SetState, even if the object is not active, Playmaker will actually run the state and go over all the actions. I would expect it to set the state to run when I enable it, and not immediately. But because it runs it as the FSM is disabled, it doesn't work as it should and events get "stuck".
It's not as over-engineered as trying to work around limitations set by how playmaker works. If I had access to Playmaker code I'd fix it with several lines and avoid all this.

Templates are great but it's only for future FSMs, it won't help me with the FSMs I already have.

Anyway, I managed to find a solution to all this by editing some FSMs in editor mode. It works nicely.