playMaker

Author Topic: What's the 'official' Playmaker way to work with prefabs and variables?  (Read 15533 times)

FritsLyn

  • Full Member
  • ***
  • Posts: 191
Over the past year or so I have spend a LOT of time on all the prefab/global variable bugs in Playmaker, and one version after the other learned how to work around things.

I thought that most issues where solved by now, and I thought I had a way to work with things. My way was this:

* Any Game Object that needed to be referenced to by actions in other Prefab's Game Objects would have to 'Initiate' themselves by setting a global Game Object variable in their name (with the suffix _global_holder).

* All other prefabs could then relate to this game object (even if it was a child inside a prefab) by simply referring to for instance Camera_global_holder global variable.

This has worked for me..

.. until recently where I'm back in old hell where Playmaker tells me that Prefabbed Game Objects may not reference to Scene objects, and Playmaker is editing my actions and setting my variables in the prefabs to 'None' - which destroys my entire project..

What on earth is one to do?

Is it really not possible for instance to:

Have a 'camera game object' inside a 'Main character prefab', and when playing sounds in other prefabs then setting the position to where this camera is?

Is it really not possible without PlayMaker deleting variables??

What's the 'official' Playmaker way to work with prefabs and (global) variables?
« Last Edit: June 13, 2014, 05:09:10 PM by FritsLyn »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
Project assets (Prefabs, FSM Templates, and Global Variables) cannot store references to scene objects. Even if the UI lets you reference a scene object (it shouldn't) the reference will not survive reloading the project. This is a limitation in Unity. I've found a couple of places where the Playmaker UI lets you drag a scene reference into a project asset - this will be fixed in the next update. I'm also adding more feedback in the editor to explain these rules.

Scene objects CAN reference project assets. So a scene object can store a reference to a template or global variable. You can set a global variable to reference a scene object at runtime.

If you're seeing a global variable lose its value and reset to none, then chances are it was referencing a scene object. However, if you see a variable selection field lose its reference to a global variable (e.g., switch from the name of the global variable to none) then it's a bug! I'm not sure which behavior you're seeing from your post...

FritsLyn

  • Full Member
  • ***
  • Posts: 191
What I am seeing is this:

A Prefab in a scene. Let's call it PrefabX
The PrefabX is not changed by me at any point in the following.

The PrefabX has a value in a field in an FSM set to be a global variable.
Many prefabs in the whole project has many references to global variables, some are instantiated in this scene, some in other scenes.

I import a new Unity Package into the project. It is from third party, and has zero PlayMaker functionalities in it.

As seen before, all the sudden Playmaker wanrs me of ..maybe 28 errors in my project - that had a green light just before.

I press play, and they all vanish.

Did I not press play but looked into the console and the affected Prefabs, I would be warned about this 'Prefabs not allowed to reference to scene objects'.

Recently I have been able to positively confirm what I was uncertain about earlier: PrefabX had 2 references to global variables, and both where reset to 'none' at playtime: The game did not work, I looked and they where set to 'None'.

I set them again, saved and refreshed, did various things to confirm that the prefab was using the Global variable 2 places.. press play, and viola! - set to None again.

Off course it's pretty hard to debug when one is in reality trying to debug ones own code - but the above is 100% confirmed.

Only other clue I can give is that I'm pretty sure that the affected PrefabX was shown in the editor just prior to pressing Play.

...

So: You tell me that what I do IS in fact the right way, the way you suggest to do it? (Let Game objects set themselves to be 'represented' by global variables at runtime?)

If so, may I suggest a tool set to work with this? Because right now, if 10 prefabs are going to reference 1 other Prefab, the 10 first have to wait for the 1 to identify itself.

In other words because of this 'system', all Game objects has to wait a couple of frames at game start to make sure their freinds have represented themselves to their 'cover address' in a Global GameObject variable.

That makes the 'identify and wait' a very standard thing to do - and so maybe there should be an action or setting for this?

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
Quote
I import a new Unity Package into the project. It is from third party, and has zero PlayMaker functionalities in it.

As seen before, all the sudden Playmaker wanrs me of ..maybe 28 errors in my project - that had a green light just before.

What were the errors?
Were there any errors in the console?
What was the package? Maybe there are conflicts?
Can you reliably repeat the bug with this sequence of actions?
If so, can you share the project with me?

FritsLyn

  • Full Member
  • ***
  • Posts: 191
Quote
What were the errors?
They are the standard 'Prefabs should not reference Scene objects'

Quote
Were there any errors in the console?
No. Not to my knowledge - apart from all the PlayMaker red flags..

Quote
What was the package? Maybe there are conflicts?
It happens now and then, packages are without any scripting, just bundles of models etc. No PlayMaker DLL or anything of the sorts.

Quote
Can you reliably repeat the bug with this sequence of actions?
Next time I'll make a fork and try and set up a repeating-bug environment.

Quote
If so, can you share the project with me?
Sure!

And how about this:

Quote
So: You tell me that what I do IS in fact the right way, the way you suggest to do it? (Let Game objects set themselves to be 'represented' by global variables at runtime?)

If so, may I suggest a tool set to work with this? Because right now, if 10 prefabs are going to reference 1 other Prefab, the 10 first have to wait for the 1 to identify itself.

In other words because of this 'system', all Game objects has to wait a couple of frames at game start to make sure their freinds have represented themselves to their 'cover address' in a Global GameObject variable.

That makes the 'identify and wait' a very standard thing to do - and so maybe there should be an action or setting for this?

?

:)

Maybe a check box at a GameObject with a FSM on it: 'Dump me as a Global Variable to be referenced'?


FritsLyn

  • Full Member
  • ***
  • Posts: 191
OK, I think I've found one sure way to provoke the bug - or a version of it:

* Have 2 separate projects, both using prefabs with references to global GameObejct variables.

* In one make a .unitypackage (Select prefab, select dependencies, uncheck select dependencies in list, uncheck PlayMaker.DLL) - and save outside

* In the other import this .unitypackage

All references to global variables in the exported are now gone at import - or at least PlayMaker warns about this.

Note: This was not the way I did things before, earlier I was not involving 2 PlayMaker related projects, and it was the project into which something was Imported (not the Imported prefab) that had trouble..

Yet, the above is (also) a bug, it might be the same, and it can be reproduced.

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
I think this is a different issue. If you Export Global Variables from the first project, then Import Global Variables into the second project BEFORE importing the unitypackage, then the imported FSMs should find the Global Variables. Otherwise the referenced global variables do not exist in the second project.

Unless you're saying the global variables DO exist in the seconds project but are not found when importing the unitypackage...?

FritsLyn

  • Full Member
  • ***
  • Posts: 191
OK, Fair enough, that is probably another issue.

However, It just happened again, but impossible to reproduce: This time I saw zero errors in the console or anywhere, everything worked fine.

I edit a n instance of a prefab, and it just says 'None (GameObject)' where the variable should be (and somewhat was, as things where working).

Once I inserted the variable the error is no longer present.. for now.

Please, would you mind answering my question(s) of A) Is this the official way to work with Prefabs/Variables - and B) If so, would you consider making it easier: One has to make sure all prefabs are hooked up manually this way, and are not referencing each other before their friends are initialized etc - it's a mess and a check box would be nice!

FritsLyn

  • Full Member
  • ***
  • Posts: 191
Reproduceable:

1 Prefab holds several GameObjects, 1 of which is setting itself up to be represented via a global game object variable.

Now it is decided that this 1 GameObject should not be a part of the prefab (That prefab is in every scene, but the mentioned Game Object needs individual adoption, so it is dragged out of the prefab, which causes the prefab connection to get lost and the one GameObject is out in a local copy.

Everything works.

Now the original prefab had a mistake made on it, and in the inspector is clicked to 'Revert'. This means that the original prefab now (again) has the GameObject with the self-initializing GameObject Global variable inside it - the one that is also out in a local copy.

In the Prefab (instantiated version) that copy of the GameObject is deleted.

And that destroys the project!

Because all the sudden the local copy of the GameObject (no longer a prefab) has all references to the global variable deleted. And in fact the global variable is completely wiped from the project, so all is destroyed.

Back to backup once again!

Again this is / was not the steps / way I experienced the bug the first time, but I'm doing what I can to find things you can reproduce - and this one appears consistent.

Summary: A Global variable was deleted when it was in fact in use elsewhere. It was deleted in an instantiated prefab, and thereby lost from the whole project.

FritsLyn

  • Full Member
  • ***
  • Posts: 191
OK, Variables changing in front of my eyes on an 'unmounted' prefab..

Note the 90/360 -value field - just when the camera is panning it is changing value when I activate the field with the mouse..

Not a valid youtube URL[/youtube]

(What's up with UT embeds? :)
« Last Edit: June 16, 2014, 07:04:47 PM by FritsLyn »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
Are you pressing enter after editing the field?
Is each camera an instance of the same prefab?
I'll try to repro here...

FritsLyn

  • Full Member
  • ***
  • Posts: 191
No keys pressed at any time - mouse only!

Everything is on the same prefab, but it is 'disconnected'. (Yellow)

FritsLyn

  • Full Member
  • ***
  • Posts: 191
Was double checking that I had latest version / that an old DLL had not snug in.. To my surprise there's inconsistency between asset store and 'About' - see attached.

And mind you, this is no matter how much I update.

Related? Is it possible to have pulled some dirt in from when prefabs did not work? How would I rinse without dumping my project?

It appears to me that you are avoiding answering my original (repeated 3 times here) question ;)

(Is this the official way to work with variables and prefabs, and if so should we not make it a little more streamlined so it is not needed to make all sorts of 'initialize me as a global reference and do not reference me before I am initialized´ - moves?)

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
No keys pressed at any time - mouse only!

Everything is on the same prefab, but it is 'disconnected'. (Yellow)

I would try pressing enter or tab.  I'll look into what's going on there...

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 4141
  • Official Playmaker Support
    • LinkedIn
The about box shows the dll version info. The dlls didn't change with 1.7.7.2, it just fixed a few warnings in scripts for 4.5. So you have the right version.

Quote
It appears to me that you are avoiding answering my original (repeated 3 times here) question ;)

I'm still considering your proposal...  ;)

There's no one "official" way to do this. There are 2 common patterns:

1. FSMs that need to know about prefab instances find them at runtime and store them in local variables. E.g., if you have a manager FSM, you can give it a tag that makes it easy to find.

2. If some FSMs need to be initialized before others (for whatever reason) then you use events to coordinate the startup order. E.g., the manager FSM broadcasts an "Initialized" event when it's ready; FSMs that are dependent upon the manager being run first respond to the "Initialized" event.

I'm not too keen on a magic initialization of a global variable. It seems too hardcoded and might hide other issues - leading people to think that FSM is actually initialized when all it's really done is set a global variable. Global variables should be used sparingly (google global variables are bad). They're provided for convenience, but I'm hesitant to endorse the global variable pattern over other patterns.

But I do want to make it easier to control execution order.

I'm currently thinking of adding an Awake state to run actions in Awake. E.g., you add actions to the FSM tab. All Awake actions are guaranteed to run before the first FSM enters its start state. You could use this to, for example, initialize global variables...
« Last Edit: June 17, 2014, 09:35:52 AM by Alex Chouls »