playMaker

Author Topic: FsmBoolTest.cs  (Read 4191 times)

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14126
  • Official Playmaker Support
    • View Profile
FsmBoolTest.cs
« on: April 06, 2011, 10:10:18 PM »
Hi Everyone,

 Posting this as it really speed up my development and saves me duplicating variables all over.

Yes, it's intended to be used only once, no every frame as it will less effective than checking its own local variable in terms of speed, but for some organization, it makes perfect sense. When for example there is a fsm responsible for storing variables for a given process, while other fsm can check against them when needed. Or simply when you can't be bother spending the extra time of creating a duplicate variable, and making the actions to retrieve it, store it and finally check for it.

For convenience, I have created an Unity package, that can be downloaded here: http://dl.dropbox.com/u/17356625/Unity/playmaker/actions/FsmBoolTest.unitypackage

1: have your unity project opened
2: in the menu, select Assets->Import Package->Custom Package
3: locate and select FsmBoolTest.unitypackage on your computer
4: Click Open
5: there is one file, make sure it's selected and import
6: done, you can now access this new action in the "Logic" Action category

 Hope you find it useful,

 Bye,

 Jean


Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2011. All rights reserved.
// Modified by Jean Fabre : contact@fabrejean.net
// this is a combination of BoolTest and GetFsmBool since I don't want the extras steps required otherwise.
// I also don't feel like saving a variable for every single check from other fsm, I want to avoid redundance sometimes.
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Logic)]
[Tooltip("Sends Events based on the value of a Bool Variable from another FSM.")]
public class FsmBoolTest : FsmStateAction
{
[RequiredField]
public FsmOwnerDefault gameObject;
[UIHint(UIHint.FsmName)]
[Tooltip("Optional name of FSM on Game Object")]
public FsmString fsmName;
[RequiredField]
[UIHint(UIHint.FsmBool)]
public FsmString variableName;
[RequiredField]
[UIHint(UIHint.Variable)]

public FsmEvent isTrue;
public FsmEvent isFalse;

public bool everyFrame;

private bool storedValue;

GameObject goLastFrame;
PlayMakerFSM fsm;


public override void Reset()
{
gameObject = null;
fsmName = "";


storedValue = false;
isTrue = null;
isFalse = null;
}

public override void OnEnter()
{
DoGetFsmBool();

Fsm.Event(storedValue ? isTrue : isFalse);

if (!everyFrame)
Finish();
}

public override void OnUpdate()
{
DoGetFsmBool();

Fsm.Event(storedValue ? isTrue : isFalse);
}

void DoGetFsmBool()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null) return;

// only get the fsm component if go has changed

if (go != goLastFrame)
{
goLastFrame = go;
fsm = ActionHelpers.GetGameObjectFsm(go, fsmName.Value);
}

if (fsm == null) return;

FsmBool fsmBool = fsm.FsmVariables.GetFsmBool(variableName.Value);

if (fsmBool == null) return;

storedValue = fsmBool.Value;
}

}
}
« Last Edit: April 15, 2011, 04:26:34 AM by jeanfabre »

Alex Chouls

  • Administrator
  • Hero Member
  • *****
  • Posts: 3608
  • Official Playmaker Support
    • View Profile
    • LinkedIn
Re: FsmBoolTest.cs
« Reply #1 on: April 12, 2011, 12:51:08 AM »
Nice! Combining common actions to reduce busywork is a good strategy...

However, I'd also like to reduce some of the busywork with new features/interfaces.

For example, I'd like to auto convert between types, and have global/shared events and variables. Maybe even be able to specify the target FSM for an event, or variable right next to the event/variable popups.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14126
  • Official Playmaker Support
    • View Profile
Re: FsmBoolTest.cs
« Reply #2 on: April 12, 2011, 01:33:13 AM »
Yes,

 Putting more flexibility within the variable selection itself would basically avoid redundant actions just because one of its variable is local or in another fsm for example. Also sometimes I would say that it is good to read at a glance that this action is linking to another fsm, that's very important sometimes to avoid confusion and clarify the actual process implications. Difficult trade here, because the name of the action says a lot currently regards the scope of it ( whether is access another fsm or is only local), maybe the ability to give a custom name to the action and not just rely on its class name.

 Bye,

 Jean

MaDDoX

  • 1.2 Beta
  • Full Member
  • *
  • Posts: 165
    • View Profile
    • FluidPlay Studios
Re: FsmBoolTest.cs
« Reply #3 on: April 12, 2011, 01:58:54 PM »
However, I'd also like to reduce some of the busywork with new features/interfaces.
One thing I've been thinking about is the "global events". I haven't seen it explained anywhere (maybe it's in another inconspicuous spot on the site? :)) but I assume it's a way to receive an external event (ie. sent from another FSM) which's independent of whichever state you're at and the transitions it uses. Right? If I got it right, this works like a "stop all and do this" for the FSM, which's quite handy. My question if it could also work as a "shortcut". For instance, suppose I have a state on the far right of a graph and its finished transition should connect to a state far to the left and to the top of the graph. That'll surely create one of those terrible lines that cross over states and makes things really ugly/cluttered. If you simply define a "shortcut" as a global event on the left, this would de-clutter things, at the cost of some clarity since there won't be a directly connecting line. Maybe that could be alleviated by the ability to color those global event / shortcuts, making such connections obvious again.

While we're at it, please give us the ability to set each transition line as bezier or connector-type, it'd help a lot.

Quote
For example, I'd like to auto convert between types, and have global/shared events and variables.
Int to float and vice-versa (with some default settings) would be nice, but I'm not sure about other conversions since they're the only default ways to perform logic functions (if this, assign that, etc) inside the same state. It helps a lot to avoid graph clutter.
--
Breno "MaDDoX" Azevedo
@brenoazevedo

tobbeo

  • 1.2 Beta
  • Full Member
  • *
  • Posts: 186
    • View Profile
Re: FsmBoolTest.cs
« Reply #4 on: April 12, 2011, 04:29:17 PM »
My solution to this was my suggestion to have more control over the lines themselves. In Nuke, node based compositing package, you can put dots on the lines to control the flow of the connecting lines.

I'm not against shortcuts though :).

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14126
  • Official Playmaker Support
    • View Profile
Re: FsmBoolTest.cs
« Reply #5 on: February 22, 2012, 03:51:36 AM »
Hi,

improved version. IsTrue is not anymore required, now I check during ErrorCheck if either of isTrue or isFalse event is set. I came across a situation where I only needed the no event. I think it's better that way now.

Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2012. All rights reserved.
// Modified by Jean Fabre : contact@fabrejean.net
// this is a combination of BoolTest and GetFsmBool since I don't want the extras steps required otherwise.
// I also don't feel like saving a variable for every single check from other fsm, I want to avoid redundance sometimes.
using UnityEngine;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Logic)]
[Tooltip("Sends Events based on the value of a Bool Variable from another FSM.")]
public class FsmBoolTest : FsmStateAction
{
[RequiredField]
public FsmOwnerDefault gameObject;
[UIHint(UIHint.FsmName)]
[Tooltip("Optional name of FSM on Game Object")]
public FsmString fsmName;
[RequiredField]
[UIHint(UIHint.FsmBool)]
public FsmString variableName;

public FsmEvent isTrue;
public FsmEvent isFalse;

public bool everyFrame;

private bool storedValue;

GameObject goLastFrame;
PlayMakerFSM fsm;


public override void Reset()
{
gameObject = null;
fsmName = "";


storedValue = false;
isTrue = null;
isFalse = null;
}

public override void OnEnter()
{
DoGetFsmBool();

Fsm.Event(storedValue ? isTrue : isFalse);

if (!everyFrame)
Finish();
}

public override void OnUpdate()
{
DoGetFsmBool();

Fsm.Event(storedValue ? isTrue : isFalse);
}

void DoGetFsmBool()
{
GameObject go = Fsm.GetOwnerDefaultTarget(gameObject);
if (go == null) return;

// only get the fsm component if go has changed

if (go != goLastFrame)
{
goLastFrame = go;
fsm = ActionHelpers.GetGameObjectFsm(go, fsmName.Value);
}

if (fsm == null) return;

FsmBool fsmBool = fsm.FsmVariables.GetFsmBool(variableName.Value);

if (fsmBool == null) return;

storedValue = fsmBool.Value;
}

public override string ErrorCheck()
{
if (isTrue ==null && isFalse==null)
{
return "You need to at least have isTrue or IsFalse event defined.";
}
return "";
}

}
}

 Bye,

 Jean

ColeBK

  • Playmaker Newbie
  • *
  • Posts: 16
    • View Profile
Re: FsmBoolTest.cs
« Reply #6 on: February 03, 2014, 10:29:22 AM »
Hi Jean,

I tried to use your FSM Bool Test action, but it crashes Unity when I press Play.

I think it's not a problem with your FSM Bool Test Action, as I've tried to solve it with a simple Bool Test called on a Global Variable, but it did the same thing:
Crashed Unity.

This must be a problem with accessing non-local variables, but I can't figure out how to solve this. Can you help me, please?

Thank you.


Lane

  • Administrator
  • Hero Member
  • *****
  • Posts: 2488
  • Yup.
    • View Profile
    • Cleverous
Re: FsmBoolTest.cs
« Reply #7 on: February 03, 2014, 10:39:24 AM »
Hi Jean,

I tried to use your FSM Bool Test action, but it crashes Unity when I press Play.

I think it's not a problem with your FSM Bool Test Action, as I've tried to solve it with a simple Bool Test called on a Global Variable, but it did the same thing:
Crashed Unity.

This must be a problem with accessing non-local variables, but I can't figure out how to solve this. Can you help me, please?

Thank you.

I just tested this with no crash. Are you using the latest PlayMaker version?

ColeBK

  • Playmaker Newbie
  • *
  • Posts: 16
    • View Profile
Re: FsmBoolTest.cs
« Reply #8 on: February 03, 2014, 10:48:26 AM »
I'm using 1.7.3.

But as I said it's not  really a problem with Jean's Action, because using simple Bool Test on a Global Variable causes the same crash. I'm really asking help for that :)

Thank you.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 14126
  • Official Playmaker Support
    • View Profile
Re: FsmBoolTest.cs
« Reply #9 on: February 04, 2014, 03:54:13 AM »
Hi,

 Can you pm me with a repro package?

bye,

 Jean