Playmaker Forum

PlayMaker Help & Tips => PlayMaker Help => Topic started by: Mayhem on August 30, 2013, 03:13:00 PM

Title: Restart Level Action loading level twice?
Post by: Mayhem on August 30, 2013, 03:13:00 PM
Hey there,

so I had an issue with another plugin after using the Restart Level Action. The developer of the plugin looked into it and told me this:

Quote
With the SoundManagerPro debug logs on (check 'Show Debug Info'), I noticed that PlayMakers call to Restart Level is loading the level twice immediately (which is making SoundManagerPro essentially run it's functions in Awake on the second load). You might want to contact them about that, because I'm sure that's not intended behavior.

Let me know if that's not what's happening to you. With the Debug logs on, it'll show something like this:
(2.489183) In Level Loaded: Sandbox
If that shows up twice exactly the same(the number in parenthesis is the time it is called), then something is wrong with their restart level.

Is there something wrong with that action?

Edit:

Same stuff with the Level-Load-Action...
Title: Re: Restart Level Action loading level twice?
Post by: Alex Chouls on August 31, 2013, 09:51:44 AM
Can you submit a bug report: PlayMaker > Tools > Submit Bug Report

When you get the link to the bug, please attach a small repro project if possible.

I'm travelling back from Unite, but I can look at this first thing next week...
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on August 31, 2013, 11:54:09 AM
Well I can't actually attach a sample scene, but I can explain it:

- when you have an empty scene with only SoundManagerPro and PlayMaker and use either the "Restart Level" or any of the "Load Level"-Actions then you'll get an Error in SoundManagerPro:

Quote
IndexOutOfRangeException: Array index is out of range.
SoundManager.CheckWhosPlaying () (at Assets/SoundManagerPro/Scripts/Managers/SoundManager_Internal.cs:131)
SoundManager.PlayClip (UnityEngine.AudioClip clip2play) (at Assets/SoundManagerPro/Scripts/Managers/SoundManager_Internal.cs:34
SoundManager+<PlaySoundConnection>c__Iterator12.Mo veNext () (at Assets/SoundManagerPro/Scripts/Managers/SoundManager_Internal.cs:74
UnityEngine.MonoBehaviour:StartCoroutine(String, Object)
SoundManager:HandleLevel(Int32) (at Assets/SoundManagerPro/Scripts/Managers/SoundManager_Internal.cs:160)
SoundManager:OnLevelWasLoaded(Int32) (at Assets/SoundManagerPro/Scripts/Managers/SoundManager.cs:24)

I asked the dev of the SoundManagerPro Plugin and as already posted in the Unity-Topic, he told me this:

Quote
With the SoundManagerPro debug logs on (check 'Show Debug Info'), I noticed that PlayMakers call to Restart Level is loading the level twice immediately (which is making SoundManagerPro essentially run it's functions in Awake on the second load). You might want to contact them about that, because I'm sure that's not intended behavior.

Let me know if that's not what's happening to you. With the Debug logs on, it'll show something like this:
(2.489183) In Level Loaded: Sandbox
If that shows up twice exactly the same(the number in parenthesis is the time it is called), then something is wrong with their restart level.

And it showed up twice at my side, so it has to be a bug, I guess. So the Actions are loading the level twice and I guess this is not intended.
Title: Re: Restart Level Action loading level twice?
Post by: Alex Chouls on August 31, 2013, 01:24:32 PM
When using Restart Level it's very easy to create a loop without meaning to since all GameObjects in the scene are reset when the level is loaded. So if Restart Level is in the start state it will get called again when the level is re-loaded.

This may be what you're seeing... Where is your Restart Level action? When are you calling it?

EDIT: For example, try Restarting the level on some user input (pressing a key). Does it still call SoundManagerPro twice?
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on August 31, 2013, 01:32:57 PM
I have one certain Restart-Button which has one FSM.

The first state is empty and has only one transition called "OnClick" (UIEventsToPlayMaker-Script for NGUI Buttons!), when OnClick is triggered it goes to the second state, which only has that Restart-Level-Action. So it's definitely not in the Start-State.
Title: Re: Restart Level Action loading level twice?
Post by: Lane on August 31, 2013, 01:54:29 PM
Try using a keyboard key to trigger the restart level state and see if it persists.
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on August 31, 2013, 02:02:02 PM
Tried it, it still persists :/
Title: Re: Restart Level Action loading level twice?
Post by: Alex Chouls on August 31, 2013, 02:08:45 PM
I just did a quick test with a MonoBehavior logging on Awake and Start and it's definitely not loading the level twice. There's something else going on. I'll need to look at SoundManagerPro to debug it...

Is SoundManagerPro using a custom action? Does it happen with the Playmaker editor closed?
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on August 31, 2013, 02:12:39 PM
No. I don't use any SoundManagerPro-related actions at all. There is only a SoundManagerObject with the SoundManager Script attached, and there you can select the AudioClips which shall play. No PlayMaker involved there.
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on September 10, 2013, 02:55:33 AM
Hi,

 Using the log from soundManagerPro, can you trace from where exactly the second level loading comes from?

Usually, to debug this kind of issues, I edit the custom action in question to put logs, so that I know exactly when and who fired the offensive second loading. Else, it's difficult to track since the debug flow of playmaker loose what happens prior the loading.

 If you have problem editing custom actions, let me know, I can help you.

 Bye,

 Jean
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on September 10, 2013, 10:47:27 AM
Where and what exactly should I DebugLog?
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on September 11, 2013, 12:11:10 AM
Hi,

 ok:

-- In the action browser, locate the "LoadLevelNum" action.
-- Right click on that action and select "Edit Script"
-- line 41, add the following: Debug.Log("Loading Level: "+levelIndex.Value);

Now when you run, you will see in the Unity console when this action is called.

 Does that help? if you are using a different action, like LoadLevel, then the debugs are already implemented.


Bye,

 Jean
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on September 19, 2013, 03:30:01 AM
Sorry for the late answer, but I wasn't at home the last couple of days.
I edited the Debug.Log in the Script and got this Info:

Quote
Loaded Level: 0
UnityEngine.Debug:Log(Object)
HutongGames.PlayMaker.Actions.LoadLevelNum:OnEnter() (at Assets/PlayMaker/Actions/LoadLevelNum.cs:42)
HutongGames.PlayMaker.FsmState:ActivateActions(Int32)
HutongGames.PlayMaker.FsmState:OnEnter()
HutongGames.PlayMaker.Fsm:EnterState(FsmState)
HutongGames.PlayMaker.Fsm:SwitchState(FsmState)
HutongGames.PlayMaker.Fsm:UpdateStateChanges()
HutongGames.PlayMaker.Fsm:DoTransition(FsmTransition, Boolean)
HutongGames.PlayMaker.Fsm:ProcessEvent(FsmEvent, FsmEventData)
HutongGames.PlayMaker.Fsm:Event(FsmEventTarget, FsmEvent)
HutongGames.PlayMaker.Fsm:Event(FsmEvent)
HutongGames.PlayMaker.Fsm:Event(String)
PlayMakerFSM:SendEvent(String)
UIEventsToPlaymakerFSM:OnClick() (at Assets/1/SCRIPTS/CustomScripts/UIEventsToPlaymakerFSM.cs:40)
UnityEngine.GameObject:SendMessage(String, Object, SendMessageOptions)
UICamera:Notify(GameObject, String, Object) (at Assets/NGUI/Scripts/UI/UICamera.cs:678)
UICamera:ProcessTouch(Boolean, Boolean) (at Assets/NGUI/Scripts/UI/UICamera.cs:1195)
UICamera:ProcessMouse() (at Assets/NGUI/Scripts/UI/UICamera.cs:946)
UICamera:Update() (at Assets/NGUI/Scripts/UI/UICamera.cs:801)

Just for the record, I don't know why and how, but the error which I mentioned above does not happen anymore? Did you guys changed something of the Restart Level Actions (LoadLevel, LoadLevelNum, Restart Level etc.) in the last PM-Updates?
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on September 20, 2013, 12:06:11 AM
Hi,

 so here, it's loading only once. Are you running other frameworks, other than playmaker? or maybe you have scripts dealing with level loading as well?

bye,

 Jean
Title: Re: Restart Level Action loading level twice?
Post by: Mayhem on September 20, 2013, 01:56:00 AM
Other Frameworks? You mean like uScript? No, I just use PlayMaker.
And no, 100% sure scripts aren't loading any level.

Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on September 20, 2013, 04:02:57 AM
Hi,

 ok, maybe I should look at the project itself then, cause there is likely something missed out.

bye,

 Jean
Title: Re: Restart Level Action loading level twice?
Post by: mschweitzer on December 05, 2013, 09:35:25 AM
Is this issue going to be addressed sometime soon? This issue was one of the last remaining bugs our team encountered that was holding up a patch release.

Not 100% sure why it happens sometimes, but it looks like PlayMaker gets confused about which state it's in after a SendEvent call and re-enters the state in the PlayMakerFSM component's Update function.

This is a *huge* problem when using iTween actions because of iTween's conflict checking feature, where iTween will destroy a previous iTween component that is similar to a newer iTween component. It means that if this bug occurs with an iTween action, the FSM will get stuck on the iTween action forever. I had to work around the problem by modifying iTween to call its "oncomplete" callbacks when it hits a conflict. This at least allowed iTween actions to finish.

Here's a stack trace of the first entry to the state:
iTween:Launch(GameObject, Hashtable)
iTween:MoveTo(GameObject, Hashtable)
HutongGames.PlayMaker.Actions.iTweenMoveTo:DoiTween()
HutongGames.PlayMaker.Actions.iTweenMoveTo:OnEnter()
HutongGames.PlayMaker.FsmState:OnEnter()
HutongGames.PlayMaker.Fsm:EnterState(FsmState)
HutongGames.PlayMaker.Fsm:SwitchState(FsmState)
HutongGames.PlayMaker.Fsm:UpdateStateChanges()
HutongGames.PlayMaker.Fsm:DoTransition(FsmTransition, Boolean)
HutongGames.PlayMaker.Fsm:ProcessEvent(FsmEvent, FsmEventData)
HutongGames.PlayMaker.Fsm:Event(FsmEventTarget, FsmEvent)
HutongGames.PlayMaker.Fsm:Event(FsmEvent)
HutongGames.PlayMaker.Fsm:Event(String)
PlayMakerFSM:SendEvent(String)
OurCustomComponent:ChangeFsmStateNow()
<WaitThenChangeFsmState>c__IteratorC6:MoveNext()

Here's a stack trace of the second entry to that same state:
iTween:Launch(GameObject, Hashtable)
iTween:MoveTo(GameObject, Hashtable)
HutongGames.PlayMaker.Actions.iTweenMoveTo:DoiTween()
HutongGames.PlayMaker.Actions.iTweenMoveTo:OnEnter()
HutongGames.PlayMaker.FsmState:OnEnter()
HutongGames.PlayMaker.Fsm:EnterState(FsmState)
HutongGames.PlayMaker.Fsm:SwitchState(FsmState)
HutongGames.PlayMaker.Fsm:UpdateStateChanges()
HutongGames.PlayMaker.Fsm:UpdateState(FsmState)
HutongGames.PlayMaker.Fsm:Update()
PlayMakerFSM:Update()

I believe the second entry to the state happens the next frame. Not sure if this has anything to do with it, but note that the SendEvent call (the first entry to the state) happens from a coroutine. We had to do this because of another PlayMaker bug where you can't use the FSM until 1 frame after you instantiate a prefab containing the FSM.
Title: Re: Restart Level Action loading level twice?
Post by: mschweitzer on December 05, 2013, 12:25:36 PM
I tried disassembling the PlayMaker.dll to follow my stack traces. Maybe the switchToState variable in the Fsm class is set correctly in the SendEvent call, then sometime before the next Update() call, it's incorrectly set back to the active state?

As far as I can tell, switchToState is only set to a non-null value in 2 functions: DoTransition() and Start(). I didn't think that DoTransition() was the culprit, so I tried looking at Start(). It looks like Start() immediately calls UpdateStateChanges(), which immediately calls SwitchState(), and my stack trace clearly shows the state switch coming from Update(), so I guess I'm not sure how the switchToState variable is being set to the same state again before the call to UpdateState() in Update().
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on December 09, 2013, 12:10:53 PM
Hi,

 Are you positive you can't solved this by refactoring the way you handle level loading and itween actions?

 I get the feeling you are over thinking this. Maybe you should simply hack this simply using a global variable or some player prefs to maintain a flag that the last level loading was handled or not.

As I am saying this, it strickes me as a deja vu :)

If you can can share with me a repro scene, I would look at it. Did you feel a but report on this already?


bye,

 Jean
Title: Re: Restart Level Action loading level twice?
Post by: mschweitzer on December 11, 2013, 10:31:52 AM
I think you're confused about what the problem is here. This isn't a level loading problem. This is a problem where PlayMaker is entering a state twice, which means it is executing actions twice.

In Mayhem's case, it meant that his level load action happened twice.
For me, it meant that my iTween action happened twice.

I think for weird cases like this, giving people source code would at least let us identify the cause of the problem. That could take maybe a couple hours or less. When you have to create a repro scene for bugs like this, there is a lot of guesswork involved because you're not 100% sure what's causing the problem. Also, you could end up failing to create a scene that perfectly mirrors what you have in your original scene, which means that the bug would just never be fixed.
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on December 11, 2013, 12:36:57 PM
Hi,

 I didn't assume it's a loadlevel issue herem and I agree: making repro projects requires skills and patience.

 I am having this very issue with the new 2d physics collision, a nightmare! I get repeated TRIGGER ENTER events ( outside playmaker, in an actual regular scripts provided by unity learning team...) and the actually unity sample simply accepts that ( which is beyond me...) and simply listen and filters accordingly. That's why I am having some trouble providing the unity 2d sample as a playmaker solution, I need to overcome this first because within Playmaker, everyone would get very confused, and for very good reasons... but I fail to find a workaround since it's coming from Unity itself to begin with...

Back to your case :)

What could be happening is something outside playmaker, and playmaker simply forward the call twice, because it indeed received it twice... that's likely the case ( can't really say for sure, but 90% sure)

So, you are not alone here :) and the quickest solution is to "accept" it and maintain flags. I am not saying it's a good solution...  :o but it's one that will let you move on.

Can you come back to me next week or aftetr xmas ( I know.. it's far away... but I am swamped...) and keep bumping me so that I have a proper look at this and point at the source of the problem for sure.

Bye,

 Jean

Title: Re: Restart Level Action loading level twice?
Post by: mschweitzer on December 11, 2013, 02:54:58 PM
Ah ok, sorry for assuming you thought it was a level loading issue..

The problem we have is that the PlayMaker state machine exposing the bug only does so under very specific conditions in our game. Unfortunately, those conditions aren't obvious at all because there's nothing about the state machine itself or the component sending the event to the state machine that would indicate this could happen.

That's why I started poking around in decompiled PlayMaker code. The only lead I have is that the switchToState variable in the PlayMaker component is getting reset within the current frame or next frame somehow. I'm just wondering how that's possible. I'm suspicious of an initialization bug in PlayMaker because there is some weird initialization code in there, and there have been bugs with PlayMaker initialization code in the past. In the stack traces I pasted earlier, the first stack trace is fine, and expected (switchToState is changing because I call SendEvent on the FSM), but the second stack trace is very mysterious to me. Somehow, from an Update() loop, the switchToState variable is being reset to the active event.

I already worked around the problem by changing iTween itself, so I'm not waiting on this any more. Would just be nice if the issue were fixed. Unfortunately, I don't have a lot of time to work on repro projects since we have deadlines to meet and it would be difficult to justify burning a few work days trying to discover how to reproduce a PlayMaker bug =\

Hopefully enough users out there run into this bug to the point where someone can narrow down whether this is an avoidable user error or a PlayMaker bug.

Thanks jean.
Title: Re: Restart Level Action loading level twice?
Post by: jeanfabre on December 12, 2013, 04:11:26 AM
Hi,

 Are you part of the beta? If you want to, pm me. you may very well be narrowing an issue for sure.

bye,

 Jean