playMaker

Author Topic: Unity Array to Playmaker Array in Custom Action  (Read 3152 times)

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
    • View Profile
Unity Array to Playmaker Array in Custom Action
« on: March 12, 2017, 01:14:43 AM »
Hi,

Trying to figure this out.  Creating custom action to create unity array of gameobjects filtered on basic their name contains in part a string and then pass that unity array to a playmaker fsm array.

Could someone post some helpful pseudo code on that?

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
    • View Profile
Re: Unity Array to Playmaker Array in Custom Action
« Reply #1 on: March 12, 2017, 02:55:34 AM »
@ All,

I did find this code for a custom action which helps my thinking A LOT... :-
Code: [Select]
// (c) Copyright HutongGames, LLC 2010-2015. All rights reserved.
/*--- __ECO__ __ACTION__ __BETA__ ---*/

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.Array)]
[Tooltip("Get all children of a gameobject and save them in an Array.")]
public class GetGameObjectChildrenInArray : FsmStateAction
{
[RequiredField]
[Tooltip("The gameObject Variable to get its children from.")]
public FsmOwnerDefault gameObject;

[RequiredField]
[UIHint(UIHint.Variable)]
[Tooltip("The Array Variable to use.")]
public FsmArray array;

[UIHint(UIHint.Layer)]
[Tooltip("Only consider objects from these layers.")]
public FsmInt[] layerMask;

[Tooltip("Invert the mask, so you pick from all layers except those defined above.")]
public FsmBool invertMask;

[UIHint(UIHint.Tag)]
[Tooltip("Filter by Tag")]
public FsmString withTag;

public override void Reset ()
{
gameObject = null;
array = null;
withTag = "Untagged";
layerMask = null;
invertMask = null;

}

// Code that runs on entering the state.
public override void OnEnter ()
{
DoGetChilds ();
Finish ();
}

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

int _layerMask = ActionHelpers.LayerArrayToLayerMask(layerMask, invertMask.Value);


List<GameObject> _list = new List<GameObject>();

foreach (Transform child in go.transform)
{
bool _valid = true;
// tag filtering
if (! string.IsNullOrEmpty(withTag.Value) || withTag.Value != "UnTagged")
{
_valid = child.tag == withTag.Value;

}

// layer filtering, if still valid
if (_valid) _valid = (_layerMask & (1 << child.gameObject.layer)) > 0 ;


if (_valid) _list.Add(child.gameObject);
}

array.Values = _list.ToArray();
}

}
}

So it's that last array.Values = _list.ToArray(); which helps the most.

If I am reading that correctly, an fsm array uses .Values rather than, as with other fsm variables a .Value.  Also, it would seem I can just transpose across any old (same variable type) unity array - and I can (if the List<T>) is simple also copy across an unity List<T> if we're just talking about a single variable (unity variable) List...?

Please someone tell me if I am wrong in some way...?

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
    • View Profile
Re: Unity Array to Playmaker Array in Custom Action
« Reply #2 on: March 12, 2017, 09:06:13 AM »
I've ploughed ahead in the absence of an immediate response (very impatient, aren't I!).

So I was looking at a Playmaker Custom Action to produce an Array of all GameObjects in Scene or Build or Resources with a Name that contains a certain string (or is a certain string) (case sensitive).

I came up with something - I'd be grateful if someone could check and point out if they thing it would work well or has flaws...

Anyways, here it is:-

Code: [Select]
using UnityEngine;
//using System;
//using System.Collections;
//using System.Collections.Generic;
using System.Linq;

#pragma warning disable 168

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.GameObject)]
[Tooltip("Finds any GameObject(s) with a Name that contains a particular String and stores them in a FSM Array.")]
public class FindGameObjectsWithNameContaining : FsmStateAction
{
        [UIHint(UIHint.FsmString)]
        [Tooltip("Find any GameObject(s) with a Name containing this string (Case sensitive).")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining;

[RequiredField]
[UIHint(UIHint.Variable)]
        [Tooltip("Store the result in an FSM Array of found GameObject(s).")]
        [VariableType(VariableType.Array)]
        public FsmArray store;
        public override void Reset()
{
withNameContaining = null;
store = null;
}

public override void OnEnter()
{
Find();
Finish();
}

void Find()
{
            if (!string.IsNullOrEmpty(withNameContaining.Value))
            {
                var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.Contains(withNameContaining.Value)).ToList();
                store.Values = taggedObjects.ToArray();
            }
        }

public override string ErrorCheck()
{
if (string.IsNullOrEmpty(withNameContaining.Value))
{
    return "Specify String to be found within GameObject(s') Name(s).";
}
return null;
}
}
}

And notwithstanding the use of Lists, I'm not sure I actually need the bit of the code which goes:-
Code: [Select]
using System;
using System.Collections;
using System.Collections.Generic;

???

If the above code is good for a Custom Action to find any GameObjects with a Name which includes a certain string (???), then it follows that the following Custom Action script would then be good to find any GameObjects with a Tag which includes a certain string?:-

Code: [Select]
using UnityEngine;
//using System;
//using System.Collections;
//using System.Collections.Generic;
using System.Linq;

#pragma warning disable 168

namespace HutongGames.PlayMaker.Actions
{
[ActionCategory(ActionCategory.GameObject)]
[Tooltip("Finds any GameObject(s) with a Tag that contains a particular String and stores them in a FSM Array.")]
public class FindGameObjectsWithTagContaining : FsmStateAction
{
        [UIHint(UIHint.FsmString)]
        [Tooltip("Find any GameObject(s) with a Tag containing this string (Case sensitive).")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining;

[RequiredField]
[UIHint(UIHint.Variable)]
        [Tooltip("Store the result in an FSM Array of found GameObject(s).")]
        [VariableType(VariableType.Array)]
        public FsmArray store;

        public override void Reset()
{
withTagContaining = null;
store = null;
}

public override void OnEnter()
{
Find();
Finish();
}

void Find()
{
            if (!string.IsNullOrEmpty(withTagContaining.Value))
            {
                var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.Contains(withTagContaining.Value)).ToList();
                store.Values = taggedObjects.ToArray();
            }
        }

public override string ErrorCheck()
{
if (string.IsNullOrEmpty(withTagContaining.Value))
{
    return "Specify String to be found within GameObject(s') Tag(s).";
}
return null;
}
}
}

It seems to work...  :)
« Last Edit: March 12, 2017, 12:03:27 PM by Duffer »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15330
  • Official Playmaker Support
    • View Profile
Re: Unity Array to Playmaker Array in Custom Action
« Reply #3 on: April 09, 2017, 11:38:24 PM »
Hi,

 that's all about right from what I can see in the code.

 the using statements will give you trouble if you remove them and they are needed, so if your action works without them using statement, they are indeed not needed.

 Bye,

 Jean

vonnero

  • Playmaker Newbie
  • *
  • Posts: 1
    • View Profile
Re: Unity Array to Playmaker Array in Custom Action
« Reply #4 on: July 08, 2017, 12:55:31 PM »
to produce an array of gameobjects, you can try this

    [ArrayEditor(VariableType.GameObject)]
      public FsmArray pmArray;

assuming you have the gameobjects on a variable called myGameobjects which is a simple GameObject[], the try this:
   
    pmArray.Resize(myGameobjects.Length);  // set the playmaker array size
    for (int i = 0; i < myGameobjects.Length; i++) //loop gameobjects
        pmArray.Set(i, myGameobjects);   // use the Set method to add to PM array