Playmaker Forum
PlayMaker Help & Tips => PlayMaker Help => Topic started by: Kein on July 06, 2017, 06:14:31 AM
-
So I'm iterating though GO and i want to get/print all FSM variables of a specific gameobject runtime, is it possible?
-
Hi,
You can use 'Get Fsm....' Actions to get the variables
Here is a video explaining Get Fsm Actions :
-
Thanks but I mean through API during runtime, no Editor (obviously I could just check it there what is set to happen), just through default script attached to dummy object in the scene I want to get list of all variables on specific GO and iterate through each of it to retrieve value
-
To clarify, you want to print all the variables of a FSM to a string or series of strings to display in the scene during run time?
If not a string, where do you want to save the values?
-
To clarify, you want to print all the variables of a FSM to a string or series of strings to display in the scene during run time?
If not a string, where do you want to save the values?
Basically I'm doing this right now:
NamedVariable[] allNamedVariables = g3.GetComponent<PlayMakerFSM>().FsmVariables.GetAllNamedVariables();
for (int k = 0; k < allNamedVariables.Length; k++)
{
Debug.Log(allNamedVariables[k].ToString());
}
Ir returns me VALUES of some variables but not all of them, I need all children too. Well, components, not children.
This does not return much useful info:
foreach (PlayMakerFSM c in GameObject.Find("myObjectMa,e").GetComponents<PlayMakerFSM>())
{
Debug.Log(string.Concat(new object[]
{
"name ",
c.name,
" type ",
c.GetType(),
" basetype ",
c.GetType().BaseType
}));
foreach (FieldInfo fi in c.GetType().GetFields())
{
object obj = c;
Debug.Log(string.Concat(new object[]
{
"fi name ",
fi.Name,
" val ",
fi.GetValue(obj)
}));
}
}
-
Hi,
Ah you want to get them in a script :)
I think you need to use GetComponents and place them (the multiple fsm components) in an array or list
then do the GetAllNamedVariables for each one in the array.
or get each fsm manually and set them in a variable using this :
public static PlayMakerFSM FindFsmOnGameObject(GameObject go, string fsmName)
I can't test right now, i will try tomorrow if this works (if not sorry for the wrong advice)
-
Hey, no worries djaydino. I figured it out, just forgot to update post.
I have a different question, not necessarily PM related but in case someone is bored I'd appreciate a hint.
So, right now I iterate through all GameObjects in the scene to find objects that on specific layer. Then I again iterate through these narrowed objects to find the ones that have component "VeryImportantComponent" so I can get the value of "VeryImportantVar" from that component.
Is there an existing PM method that just gets me list of all gameObjects with specific named component?
And how do I even condition NamedVariable if I cant use normal operators like ==/!= ?
-
Hi,
is 'VeryImportantComponent' an fsm Component?
if so, after you got the GameObjects by layer, you can use :
PlayMakerFSM[] componentList = FoundGameobjectByLayer.GetComponentsInChildren<PlayMakerFSM>().ToArray();
then you need to iterate and use this :
var currentFsm = componentList [i]
var fmsName = currentFsm
if (fsmName == "FSM")
{
// get VeryImportantVar
}
if it is not a fsm component change PlayMakerFSM to VeryImportantComponent.
I don't know if it is the best or fastest way, but this should work.
-
Yeah, thanks.
Can I get list of Events for specific FMS?
-
Hi.
Yes you can :
FsmEvent[] myFsm = RegionFsm.FsmEvents.ToArray(); //for test
for (int i = 0; i < fsmName.Length; i++)
{
var fsmEventName = myFsm [i].Name;
Debug.Log(fsmEventName);
}
-
Thanks for all the tips. I'm currently using this method but it is quite slow. You do't have to answer this but if you have an idea off the top of your head how to do it faster I'd appreciate it:
GameObject[] array = UnityEngine.Object.FindObjectsOfType(typeof(GameObject)) as GameObject[];
for (int i = 0; i < array.Length; i++)
{
if (FSMUtility.LocateFSM(GameObject.Find(array[i].name), "VeryImportantFSM") != null)
{
this.fmsPool.Add(array[i].name.ToString());
}
}
Cheers!
-
Hi,
No problem :)
FindObjectsOfType is 'expensive'
Maybe you could get the fsms into an array within play maker?
and then get the array
Are these objects created @ runtime or preset?
If preset you can make an array and set the array type to 'Object' and Object Type to 'PlaymakerFSM' then you can drag the "VeryImportantFSM" into the array.
If from prefab or clone, then you can use the action i have added in the attachment. to get the fsm.
It will show the gameobject name it is in, but it has the correct fsm (if you use the correct name of course)
I have tested it a bit, but not much yet so it might not work perfectly, i will test some more later and add it to the Ecosystem (https://hutonggames.fogbugz.com/default.asp?W1181)
-
Thanks this may come in handy.
Are these objects created @ runtime or preset?
As of right now all stuff is runtime
-
So to make sure there is no way to directly fetch FSM without iterating? Even the built-in helper func does that?
-
Hi,
Have you tried my suggestions with the action i provided?
-
then you need to iterate and use this :
var currentFsm = componentList [i]
var fmsName = currentFsm
if (fsmName == "FSM")
{
// get VeryImportantVar
}
Yes, this is what you said^
Like, even if I know that MyObject has PlaymakerFSM component named "temp copmponent" attached I still have to iterate to get it. Here is example from your built-in util:
public static PlayMakerFSM LocateFSM(GameObject go, string fsmName)
{
if (go != null)
{
PlayMakerFSM[] components = go.GetComponents<PlayMakerFSM>();
if (components != null)
{
for (int i = 0; i < components.Length; i++)
{
if (components[i].FsmName == fsmName)
{
return components[i];
}
}
}
}
return null;
}
As I mentioned before I iterate through list of objects after scene loaded, I already sort them out by layer to narrow results but even if I know that these specific gameObject will have specific FSM in 99% of cases I still need to iterate through all FSM-components and find the one matching by name instead of directly requesting it.
-
Hi,
I mean from this post :
Hi,
No problem :)
FindObjectsOfType is 'expensive'
Maybe you could get the fsms into an array within play maker?
and then get the array
Are these objects created @ runtime or preset?
If preset you can make an array and set the array type to 'Object' and Object Type to 'PlaymakerFSM' then you can drag the "VeryImportantFSM" into the array.
If from prefab or clone, then you can use the action i have added in the attachment. to get the fsm.
It will show the gameobject name it is in, but it has the correct fsm (if you use the correct name of course)
I have tested it a bit, but not much yet so it might not work perfectly, i will test some more later and add it to the Ecosystem
So you would only need to get that array, something like this :
PlayMakerFSM GameObjectFsm = GameObject.GetComponent<PlayMakerFSM>();
int arrayLenght = GameObjectFsm .FsmVariables.GetFsmArray("arrayname").Length;
for (int z = 0; z < arrayLenght; z++)
{
PlayMakerFSM go = GameObjectFsm .FsmVariables.GetFsmArray("ArrayName").Get(z) as PlayMakerFSM;
// do your thing to the fsm
}
it is best to place that array on a gameobject with a single fsm. but if not possible.
Then you can something like this to get to the array :
PlayMakerFSM[] playMakerFsms = gameObject.GetComponents<PlayMakerFSM>();
for (int z = 0; z < playMakerFsms.Length; z++)
{
string currentFsmName = playMakerFsms[z].name;
if (currentFsmName == "theNeededFsm")
{
PlayMakerFSM playMakerFsm = playMakerFsms[z];
}
}
or this way :
public static PlayMakerFSM GetPlayMakerFsmByName(this GameObject gameObject, string fsmName)
{
PlayMakerFSM[] playMakerFsms = gameObject.GetComponents<PlayMakerFSM>();
return playMakerFsms.FirstOrDefault(playMakerFsm => playMakerFsm.FsmName == fsmName);
}
I found this on this website (https://matthewwaring.wordpress.com/2014/01/14/using-playmaker-with-code-quick-introduction/)
-
Thanks djaydino, but I should have specified - getting FSMs into array is no issue to me, the fact I need to iterate through them and thus affect performance is some way - is. I was hoping there was a direct way to get specific FSM knowing its name. Oh well, not a big deal.
I have another question
Hi.
Yes you can :
FsmEvent[] myFsm = RegionFsm.FsmEvents.ToArray(); //for test
for (int i = 0; i < fsmName.Length; i++)
{
var fsmEventName = myFsm [i].Name;
Debug.Log(fsmEventName);
}
As I can see I'm getting list of all events? Is there a way to narrow per FSM component?
like
PlaymakerFSM tempFMS = FSMUtility.LocateFSM(gameObject, "fms_name");
FSMevent[] events = something.GetallEventOnFSM(tempFMS);
foreach [...]
etc
?
-
Hi.
FsmEvent[] events = something.FsmEvents.ToArray();
Btw you can find some api references here (https://hutonggames.fogbugz.com/default.asp?W127) :)
-
Is there a bug in .GetAllNamedVariables() extension method? It returns me ALL named variables on all FSMs of an object, even tho I specific specific FSM.
-
Today I learned that when I iterate through NamedVar I need to do nullref check for EACH specific aspect of apparently...
NamedVariable[] allNamedVariables = curFSM.FsmVariables.GetAllNamedVariables();
if (allNamedVariables != null && allNamedVariables.Length != 0)
{
Debug.LogError("NameVars array aint null");
for (int v = 0; v < allNamedVariables.Length; v++)
{
if (allNamedVariables[v].Name != null && allNamedVariables[v] != null && allNamedVariables[v].VariableType != null)
{
Debug.LogError("Joke nullcheck passed lol");
VariableType variableType = allNamedVariables[v].VariableType;
File.AppendAllText(curFSM.FsmName + "_vars.txt", string.Concat(new object[]
{
"[name]: ",
allNamedVariables[v].Name,
" [value]: ",
allNamedVariables[v].ToString(),
" [type]: ",
allNamedVariables[v].VariableType.ToString(),
Environment.NewLine
}));
}
}
}