playMaker

Author Topic: Timing Issue  (Read 2033 times)

tman1978

  • Playmaker Newbie
  • *
  • Posts: 11
Timing Issue
« on: August 23, 2014, 04:09:55 PM »
I have an action that calls a script. In that script, I instantiate a prefab that has an FSM attached. In another state I send an event to FSM that was instantiated in the previous state. The problem I'm seeing is that at runtime the gameobject that was instantiated does not get the event. The weird thing is that when I step through the debugger, the newly created gameobject gets the event. So my guess is that this is some sort of weird timing issue. Also, if I put a state containing a 1 second Wait action between the state where the gameobject is created and the state where the event is sent, the gameobject gets the event. This further confirms that this is a timing issue.

Has anyone encountered this before and have a way other than using the Wait action to resolve this?

600

  • Beta Group
  • Hero Member
  • *
  • Posts: 713
    • Flashing Lights
Re: Timing Issue
« Reply #1 on: August 25, 2014, 08:02:16 AM »
Hello,

I have a similar setup,
when a prefab is instantiated, it asks for that event to be sent to him.

Red

  • Hero Member
  • *****
  • Posts: 563
Re: Timing Issue
« Reply #2 on: August 25, 2014, 11:58:12 AM »
Yeah, I've had stuff like this happen too... What I tend to do to get around it is to have everything set up so that when instantiating there's a check in place before going to the state that fires off the event.

So, for example, say I'm fetching a monster from the pool... But it needs to get information from the pooling controller such as who the main target is, roughly where it is, what kinds of animations/effects/particles it has to have on it and that kinda stuff.

The first thing I'll do is add in a set of actions that I want it to do before getting told to "activate." Since this object needs to get information fed to it from other systems, I'll have the string of states that it has to go through (That aren't reliant on other data being sent to it) so that is finished... Then I'll have it wait on the end of this particular string of actions with the last state having a transition that isn't "finished." so, for example, it'd be "Initialize." (you could make the initialize a global transition as well but that may not be the most ideal method for all situations since a global transition can be called from any point in the FSM whereas a transition in the state itself (aka, not global) has to be in that particular state for that transition to be actioned. So, this way I can be sure that it's not being initialized prematurely...

And when I want to get that transition fired off, I use the send event action. You can make it use non-global transitions as well because afaik it's basically that one FSM shouting at the other FSM the word "Initialize" (or whatever transition you use.) So if there are no global transitions with that and it's not in that particular state when the action gets fired off, it won't go to it's initializing states until it's there.

TL-DR: I'd use a non-global transition to control the flow so that it isn't being activated prematurely before any data can be sent to it that it may need.

tman1978

  • Playmaker Newbie
  • *
  • Posts: 11
Re: Timing Issue
« Reply #3 on: August 25, 2014, 07:08:37 PM »
Thanks for the responses guys. I resolved this issue by creating an action that waits for the event target to be in a specific state before sending the event. What I've been able to deduce is that in some cases, when you instantiate an FSM from a prefab, there is a delay of a couple frames before the instantiated prefab gets to the first state.

Here is a snippet of the code:

Code: [Select]

                   // You should grab the fsm in the OnEnter function           
                   var fsm = secondTransform.GetComponent<PlayMakerFSM>();

                   // The following code runs every frame.
            if (fsm != null)
            {
                        // Before sending the event, make sure the target FSM is in the correct
                        // state to receive the event.
                        var targetCurrentState = fsm.ActiveStateName;

                if (ExpectedState == targetCurrentState)
                {
                    Fsm.Event(eventTarget, sendEvent);

                            // The calling function calls Finish() when true is returned.
                    return true;
                }
                        // ----------------------------------------------------------------------
            }