playMaker

Author Topic: Communicating between FSMs  (Read 5712 times)

Pani

  • Playmaker Newbie
  • *
  • Posts: 4
Communicating between FSMs
« on: June 26, 2013, 06:09:14 PM »
I just bought PlayMaker and I'm very excited to dig into it, but I have a question first about FSM communication.

Say I'm making a turn-based game. As the name implies, one player does something, after which the second player does something. Here's a small example of the FSM of a unit in this turn-based game:


On "End Turn", I want to send the "Turn Start" event to the other player, which would transition into "Action Wait". What would be the best way to do this?

This is the way I'm doing it right now with a "BattleManager" object with this script attached, but I imagine there's a better or more efficient way:
Code: [Select]
void Update()
{
if (fsm[activeFSM].ActiveStateName == "turn_wait")
{
if (activeFSM >= fsm.Count-1) activeFSM = 0;
else activeFSM++;

fsm[activeFSM].SendEvent("turn_start");
}
}

fsm is a list populated by the Playmaker components of my units and activeFSM is just an integer starting at 0 as you would imagine.
« Last Edit: June 26, 2013, 09:27:04 PM by Pani »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Communicating between FSMs
« Reply #1 on: June 27, 2013, 12:57:02 AM »
Hi,

 yes, you can do all this without having to code custom actions.

if both player maintain a reference of the other, then you can use "send event" action and target the other player.

Does that make sense?

bye,

 Jean

Pani

  • Playmaker Newbie
  • *
  • Posts: 4
Re: Communicating between FSMs
« Reply #2 on: June 27, 2013, 01:14:33 AM »
How do you set up that action when the player objects are created during gameplay? They'd also occasionally be clones of the same prefab. Here's how I have it set up right now:



This FSM is on my monster prefab. Later in the game, two clones of this prefab are created to fight against each other. In turn_end, they should send turn_start to the other monster. What I have now in the screenshot isn't working, though, because I assume it's just sending the event to itself. How do I set the reference during runtime? Or what should I do?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Communicating between FSMs
« Reply #3 on: June 27, 2013, 01:49:29 AM »
Hi,

 Setting reference at runtime is easy. several ways to do it.

 If a GameObject fires an event, you can use "Get Event info" to know who sent it. So as your monster prefab Fsm Starts, it could fire an event "MONSTER IS HERE!" event and anyone interested in getting its reference can do by implementing that global event and get it's reference.

you can also manually set event data ( the gameObject property of "set event data") and then fire an event like "NEW PLAYER IS HERE!". You can also add a string data as well, so you could pass both the reference of the gameObject and in the string property something like "monster" and anyone who do not care about monster would simply receive that event, check its string value and do nothing if it's not what they are interested in.

 you can also manually set a Fsm variable from other Fsm. So using "Set Fsm gameObject", you can target a specific Fsm and set one of it's gameobject variable.

And finally, you can also use "Find gameObject", either by name and or by tag.

 Also, remember that prefab CAN NOT store reference of scenes objects, just as a warning, cause it's easy to forget about it. during run time when you instantiate a prefab you can then query and store gameobject reference in the scenes, but if you plan on keepin that reference in the prefab itself, it simply won't, that's a unity restricition.


bye,

 Jean
 

Pani

  • Playmaker Newbie
  • *
  • Posts: 4
Re: Communicating between FSMs
« Reply #4 on: June 27, 2013, 03:23:03 PM »
I think I understand except for one thing: the Get Event Info action. I'm not sure what to do with it. Does that work between FSMs? How do you use the info given through that? Right now I've set up another FSM called "BattleManager" that the monsters send a "monster_spawn" event to. However, I need them to also send their gameObject reference for BattleManager to store in a variable. How would I do that using Get Event Info?

Lastly, does PlayMaker support lists/iterating through them or  would I need to make a custom action for that? What I want to do is: each time a monster sends "monster_spawn", add them to a list in BattleManager. At index 0 in the list, send that monster "turn_start". When that monster sends "turn_end" to BattleManager, send "turn_start" to the gameObject at index 1 in the list, and so on. It would just cycle  to the end of the list, come back to index 0 and repeat.

Sorry if these questions sound basic. I know how I'd do them in code but I'm just a little confused in how to do it in PlayMaker.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Communicating between FSMs
« Reply #5 on: June 28, 2013, 01:27:38 AM »
Hi,

 Don't worry, we all started with the basics. that's part of the process.

"Get event info" is your way to get data attached to an event. So typically:

1: FSM A use "set event data" and for example set the string value to "hello"
2: FSM A sends a global event ( or any event really)
3: FSM B receives that event
4: FSM B use "get event info" and store in a string variable the string data and gets "hello"

Does that make sense now? I use this all the time. It's a very good technic to design proper systems without having to create global vars or access directly other fsm's variable when really it should not.

For lists, I wrote a full blown system called ArrayMaker. it handles ArrayList and HashTables, and you can can iterate through them, set/get/update/find/delete them, basically doing all the things you can with regular scripting, all within Playmaker.

But ArrayMaker is not "basic" per say. it requires some acquaintance with PlayMaker and also the concepts of arrays and hashtables. You will find a lot of samples with arrayMaker, so it's important you study them just to get a grasp of what's going on.

https://hutonggames.fogbugz.com/default.asp?W715


Bye,

 Jean

Pani

  • Playmaker Newbie
  • *
  • Posts: 4
Re: Communicating between FSMs
« Reply #6 on: June 28, 2013, 02:40:05 AM »
Thanks, I think I got the majority of it now. I just have two small questions left:
For some reason, when I check the box to make an event global, it won't let me uncheck it. It just keeps reverting back to its global state. What am I doing wrong?

Lastly, does "ArrayList Get Next" end at the last item, or does it loop back at 0? It seems to be stopping at the last item unless I'm doing something wrong.
« Last Edit: June 28, 2013, 05:24:23 AM by Pani »

KozTheBoss

  • Full Member
  • ***
  • Posts: 150
  • You dont fail unless you give up trying to succeed
    • Pixel Life - portfolio
Re: Communicating between FSMs
« Reply #7 on: June 29, 2013, 09:40:10 AM »
Hi Pani, I think i can help with that first question

Whenever you test the game, or it is in the "play" state, anything you do or change will be reverted back to it's previous state when you stop the game again.

What i mean is if the play button at the top of the screen is blue, and you are playing your game, then any changes you make will not be saved

Perhaps this is what you have accidentally done? :)

If that's not the case, then it indeed sounds weird! Maybe you have other actions that use that event globally, and therefore it cannot be turned off? I can't imagine that would be the case but it's worth a shot (just a theory)
If you have used that event globally then disable the event reference on the other gameobjects - maybe then you can revert it back to a private event
Remember, you don't fail unless you give up trying to succeed!

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Communicating between FSMs
« Reply #8 on: July 01, 2013, 02:15:21 AM »
Hi,

 Regards your global event going back to life. double check that you don't have that event declared in a fsm that you don't actually use in any states. It's a know issue. you need to clean up your global event and delete it from fsm where it's not used. that shoud work there after.


ArrayList GetNext should loop back, but I strongly warn you that you may hit a infinity loop warning very soon if you do that. Constant looping should be refactored to avoid this, and for example create a fsm for each gameObject that needs this and implement the logic to run on each, instead a centralized logic management


bye,

 Jean