playMaker

Author Topic: How to save an FSM?  (Read 1576 times)

GarthSmith

  • Playmaker Newbie
  • *
  • Posts: 31
  • Games. Math. Code.
    • View Profile
    • Garth Smith's Website
How to save an FSM?
« on: December 05, 2013, 01:21:09 PM »
Hello!

I have a GameObject with an FSM attached. I would like to know how to save the current state of the FSM. How can I go through this process:

  • FSM is on a certain state.
  • Save FSM.
  • Destroy FSM.
  • Instantiate another instance FSM.
  • Set new FSM to be in the same state and have same variable values as previously destroyed FSM.

GarthSmith

  • Playmaker Newbie
  • *
  • Posts: 31
  • Games. Math. Code.
    • View Profile
    • Garth Smith's Website
Re: How to save an FSM?
« Reply #1 on: December 05, 2013, 02:02:33 PM »
It looks like I can grab all the variable values on an FSM and then set them again. So that part shouldn't be a problem.

I still don't know how to go to a specific state. I can save the state name, and call a global transition when I load the FSM again. I really don't want to do this because this means we have to add a different global transition manually to every state which takes a lot of time and has a lot of opportunities to make typos.

GarthSmith

  • Playmaker Newbie
  • *
  • Posts: 31
  • Games. Math. Code.
    • View Profile
    • Garth Smith's Website
Re: How to save an FSM?
« Reply #2 on: December 05, 2013, 02:46:46 PM »
Alright, I got something together that seems to be working. I create a global transition at runtime to the state I want to go to. Is this really the best way to jump to a specific state?
Code: [Select]
public void Load() {

    // STEP 1: Which state do I want to jump to?
    string savedStateName = PlayerPrefs.GetString(id, "");
    if (!string.IsNullOrEmpty(savedStateName)) {

        // STEP 2: Make a global transition to that state.
        List<FsmTransition> globalTransitionList = new List<FsmTransition>(m_fsm.Fsm.GlobalTransitions);
        FsmTransition stateTransition = new FsmTransition();
        stateTransition.ToState = savedStateName;
        stateTransition.FsmEvent = new FsmEvent(savedStateName);
        globalTransitionList.Add (stateTransition);
        m_fsm.Fsm.GlobalTransitions = globalTransitionList.ToArray ();

        // STEP 3: Use the freshly made global transition
        m_fsm.SendEvent(savedStateName);
    }
}
« Last Edit: December 05, 2013, 03:16:58 PM by GarthSmith »

GarthSmith

  • Playmaker Newbie
  • *
  • Posts: 31
  • Games. Math. Code.
    • View Profile
    • Garth Smith's Website
Re: How to save an FSM?
« Reply #3 on: December 05, 2013, 06:32:06 PM »
Had to change one line:
Code: [Select]
// Old.
// m_fsm.SendEvent(savedStateName);
// New.
m_fsm.Fsm.Event(stateTransition.FsmEvent);

Andy22

  • Junior Playmaker
  • **
  • Posts: 99
    • View Profile
Re: How to save an FSM?
« Reply #4 on: December 06, 2013, 03:19:12 AM »
Is this really the best way to jump to a specific state?

Not really, u don't actually save a FSM, but rather emulate a event.
There is/was this plugin http://whydoidoit.com/unityserializer/, but the dev is in limbo for nearly a year and some issues popped up for Unity 4.1+. It looks fixable, but no one took the time to fix/advance the project yet.

We try to write our FSM's to-be self contained and "repairing", this means we use a Init() startstate that ensures the FSM gets initialized correctly.
If u rely on some external saved data i would put a "save" component on a gameobject and save the values there and check them in the startstate and transition accordingly. This means setup your FSM in a way that u don't have to emulate a transition, but rather add a property check for the "thing" u looking for and transition normally.

bye Andy

GarthSmith

  • Playmaker Newbie
  • *
  • Posts: 31
  • Games. Math. Code.
    • View Profile
    • Garth Smith's Website
Re: How to save an FSM?
« Reply #5 on: December 06, 2013, 01:30:40 PM »
Thanks for the reply Andy! I really like the idea of an Init state that determines which state to go to next. What I have right now is working so I gotta move on but when problems start to arise I'll implement that.