PlayMaker Feedback > Feature Requests

Inter FSM event list and FSM -> Message with method call please?

(1/4) > >>

KJIB:
We are starting to use a lot of FSMs and it sometimes takes quite a while to find which FSM triggered an event in another FSM. In the events window you can see how many times an event is used. It would be great to expand that and see which FSM/State/Action uses it so we can quickly zoom into what has been set up.

It would also be great to do something similar for method calls (i.e. where a state has an action that uses Send Message to call a method) because I sometimes want to drill down to who is calling a given method.

I am guessing that both of these should be fairly straight forward, can we have them please please please? Or perhaps I'm missing something that's already there (I'm using 1.4.3f5) ?

If you really want to go to town with it you could show all the FSMs with state->events radiating out to the other FSM/states with event lines or something cool & visual. But a small tweak to see where the events are going from the existing event window would be great too.

Alex Chouls:
There are some things you can do right now:

You can right click on the event to jump to states that use it.

You can use the FSM Log to follow events by clicking on the Sent By and Target log entries.

Have you tried playing with these features?

But I agree you can never have enough tools for this kind of detective work! I'd love to make a fully visual scene explorer like you describe!

This is definitely an area I want to expand on...

KJIB:
I'd not noticed that you could right click and to see where an event is coming in from an FSM/state so that is a great help, thank you for pointing it out to me.  :)

I found that this only picks up on things sent by an FSM (I think), which is understandable. I frequently have lots of events sent to FSMs from scripts and, as the object type I'm calling SendEvent on ends up being from an FSM object (of course), I should think it's viable to pick up on that. I appreciate this this would be perhaps quite involved as I normally pass the string event name to a function that checks the FSM exists etc. before trying to send it (so sifting through all the layers would perhaps be involved)... but it sure would be handy. This also goes back to another posting I made wanting to refer to event names via a Playmaker mechanism for maintainability rather than a string in the inspector (as this would also assist you in displaying that the event is used more widely than just from FSMs in the event window).

Also! How about method calls? It would perhaps be fairly easy to list all the SendMessage calls so you could, (say, in coding utopia), click on the method call & go to the script (but just listing all the method calls sorted (say) A-Z by method name showing host FSM/state would help).

I hope you can put something in along these lines sometime, it would be a great help as projects grow & we find more ways that we can use Playmaker.

Alex Chouls:
Actually a lot of the Playmaker Editor GUI methods are public.

So for example you should be able to do this:


--- Code: ---fsmEvent = FsmEditorGUILayout.EventPopup(label, FsmEvent.EventList, fsmEvent);
--- End code ---

Where fsmEvent is of type FsmEvent.

FsmEvent.EventList contains all the events in the project.

But there are utility methods for getting other lists. E.g.:


--- Code: ---FsmEditorUtility.GetEventList(targetFsm)
--- End code ---

Rememember this:


--- Code: ---using HutongGames.PlayMakerEditor;
--- End code ---

Then you can poke around with code completion...

NOTE: I haven't tried using these outside of Playmaker! Use at your own risk - the editor API is not officially supported!

Actually, it would be cool to use the new PropertyDrawers in Unity 4 to make custom PropertyDrawers for FsmEvent and other FSM variables. So you'd get the same UI you get in Playmaker to edit these in your own scripts! Hmmm....

KJIB:
OK, Here's a free mini tool to help with this. I have it generating a very basic list of what I wanted to see. It would be easy for someone to do something far more pretty if they have some time.

I hope that you folks at Playmaker can take this under your wing and I bet you can really make the tool sing with some tweaks (I just don't have the time). Or do something much better than this.

There are just 2 files, follow the instructions for where to put them etc. in the code comments.

PlayMakerCommsToolEditor.cs

--- Code: ---using UnityEngine;
using System.Collections;

using UnityEditor;

// Show SendEvent and SendMessage actions in FSMs so you can track down what's going on in multi-FSM designs more easily.
// Put the PlayMakerCommsTool.cs script in with your normal code (NOT in the Assets/Editor directory).
// Put the PlayMakerCommsToolEditor in the Assets/Editor directory.
//
// To use:
// Once the code is in the right place you will find a new menu item "Comm Tool" under
// the Playmaker menu. Click this, you only need to do it once in a scene. Then when
// you want to see the details for SendEvent and SendMessage select the
// "PlayMakerCommsTool" from the Hierarchy and then in the inspector click the
// "Re-output Playmaker Comms (to Console)" button. Now you should see a new entry
// added to the Console, click it to get more detail. If you change stuff and want
// to see the detail just click the button again. You can delete the PlayMakerCommsTool
// object from your Hierarchy when finished.

[CustomEditor (typeof (PlayMakerCommsTool))]
public class PlayMakerCommsToolEditor : Editor {
[MenuItem ("PlayMaker/Comm Tool")]
static void Create(){
GameObject gameObject = new GameObject("PlayMakerCommsTool");
PlayMakerCommsTool s = gameObject.AddComponent<PlayMakerCommsTool>();
s.Rebuild();
}

public override void OnInspectorGUI ()
{
PlayMakerCommsTool obj;

obj = target as PlayMakerCommsTool;

if (obj == null)
{
return;
}

base.DrawDefaultInspector();
EditorGUILayout.BeginHorizontal ();

// Rebuild the comms lines when user click the Rebuild button
if (GUILayout.Button("Re-output Playmaker Comms (to Console)")){
obj.Rebuild();
}
EditorGUILayout.EndHorizontal ();
}
}

--- End code ---

PlayMakerCommsTool.cs

--- Code: ---using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using HutongGames.PlayMaker;

// Show SendEvent and SendMessage actions in FSMs so you can track down what's going on in multi-FSM designs more easily.
// Put the PlayMakerCommsTool.cs script in with your normal code (NOT in the Assets/Editor directory).
// Put the PlayMakerCommsToolEditor in the Assets/Editor directory.
//
// To use:
// Once the code is in the right place you will find a new menu item "Comm Tool" under
// the Playmaker menu. Click this, you only need to do it once in a scene. Then when
// you want to see the details for SendEvent and SendMessage select the
// "PlayMakerCommsTool" from the Hierarchy and then in the inspector click the
// "Re-output Playmaker Comms (to Console)" button. Now you should see a new entry
// added to the Console, click it to get more detail. If you change stuff and want
// to see the detail just click the button again. You can delete the PlayMakerCommsTool
// object from your Hierarchy when finished.


public class PlayMakerCommsTool : MonoBehaviour {

public bool ShowSendMessage = true;
public string FilterMethodName = "";
public bool ShowSendEvent = true;
public bool ShowEventAndMessagesTogether = false;
public string FilterStateName = "";
public string FilterFsmName = "";

public void Rebuild(){
// An array of all FSMs
PlayMakerFSM [] fsms = FindObjectsOfType(typeof(PlayMakerFSM)) as PlayMakerFSM[];

if (fsms != null)
{
string results;
results = "PlayMakerCommsTool: " + fsms.Length + " FSMs found. CLICK THIS in top panal to expand in bottom panal.\n";

foreach(PlayMakerFSM fsm in fsms)
{
if ((FilterFsmName.Length > 0) && (fsm.name != FilterFsmName)) continue;

for (int s = 0; s<fsm.FsmStates.Length; ++s)
{
if ((FilterStateName.Length > 0) && (fsm.FsmStates[s].Name != FilterStateName)) continue;

if (ShowEventAndMessagesTogether == true)
{
foreach(FsmStateAction action in fsm.FsmStates[s].Actions)
{
if ((ShowSendEvent == true) && (action.GetType() == typeof(HutongGames.PlayMaker.Actions.SendEvent)))
{
results += "SendEvent " + fsm.ToString() + " State " + fsm.FsmStates[s].Name + "\n";
}

if ((ShowSendMessage == true) && (action.GetType() == typeof(HutongGames.PlayMaker.Actions.SendMessage)))
{
HutongGames.PlayMaker.Actions.SendMessage sm = (HutongGames.PlayMaker.Actions.SendMessage)(action);
string funcName = sm.functionCall.FunctionName;

if ((FilterMethodName.Length > 0) && (FilterMethodName != funcName)) continue;

results += "SendMessage " + fsm.ToString() + " State " + fsm.FsmStates[s].Name + " call method " + funcName + "\n";
}
}
}
else
{
if (ShowSendEvent == true)
{
foreach(FsmStateAction action in fsm.FsmStates[s].Actions)
{
if (action.GetType() == typeof(HutongGames.PlayMaker.Actions.SendEvent))
{
results += "SendEvent " + fsm.ToString() + " State " + fsm.FsmStates[s].Name + "\n";
}
}
}

if (ShowSendMessage == true)
{
foreach(FsmStateAction action in fsm.FsmStates[s].Actions)
{
if (action.GetType() == typeof(HutongGames.PlayMaker.Actions.SendMessage))
{
HutongGames.PlayMaker.Actions.SendMessage sm = (HutongGames.PlayMaker.Actions.SendMessage)(action);
string funcName = sm.functionCall.FunctionName;

if ((FilterMethodName.Length > 0) && (FilterMethodName != funcName)) continue;

results += "SendMessage " + fsm.ToString() + " State " + fsm.FsmStates[s].Name + " call method " + funcName + "\n";
}
}
}
}
}
}
if (FilterMethodName.Length > 0) results += "Filter Method Name = " + FilterMethodName + "\n";
if (FilterStateName.Length > 0) results += "Filter State Name = " + FilterStateName + "\n";
if (FilterFsmName.Length > 0) results += "Filter FSM Name = " + FilterFsmName + "\n";
Debug.Log(results);
}
else
{
Debug.Log("PlayMakerCommsTool: No FSMs found");
}
}
}

--- End code ---

Tested in Unity 3.5.6f4 with Playmaker 1.4.3f5

Enjoy  :)

Navigation

[0] Message Index

[#] Next page

Go to full version