playMaker

Author Topic: Find GOs by Name (or Tag) which contains a particular String.  (Read 5865 times)

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
Hi All,

I am rather the noob here.  I posted a question and then went on to try and answer it myself here http://hutonggames.com/playmakerforum/index.php?topic=14545.msg67587#msg67587.

Rather than having to find GOs by either their Name(s) or their Tags, thought it would be nifty if you could generate/store an FSM Array of all GOs with a Name containing a particular substring OR (separate Action) all GOs with Tags containing a particular substring.

Then I went one better and thought about it potentially looking for two substrings within GO Name(s) or two substrings within GO Tag(s)...

Thought that would make Naming and Tagging of GOs a lot more versatile?  Also, you needn't then worry about MultiName or MultiTag functionality... ;)

I also added a bool (for all then 8 FSM actions) which if set to true makes the string search case insensitive...

I also added similar Count FSM Actions so you can count the number of GOs meeting the criteria (ie. containing one or two substrings in their Name or one or two substrings in their Tag)...

.... they work!  (No need for multi tags or similar anymore!  Huzzah!)

Here is the code for all EIGHT of the Custom Actions.  I have tested them and they do seem to work.

Code: [Select]
using UnityEngine;
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 an FSM Array.")]
    public class FindGameObjectsWithNameContaining : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Find any GameObject(s) with a Name containing this string.")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t2;

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

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

        void Find ()
        {
            t1 = withNameContaining.Value;
            t2 = t1.ToUpper();

            if (!string.IsNullOrEmpty(withNameContaining.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.ToUpper().Contains(t2)).ToList();
                    store.Values = taggedObjects.ToArray();
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.Contains(t1)).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;
        }
    }
}

Code: [Select]
using UnityEngine;
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 an FSM Array.")]
    public class FindGameObjectsWithNameContaining2 : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Find any GameObject(s) with a Name containing two Strings.  First this String...")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("And with the GameObject(s) having a Name containing this string too.")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining2;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t12;
        private string t2;
        private string t22;

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

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

        void Find ()
        {
            t1 = withNameContaining.Value;
            t12 = withNameContaining2.Value;
            t2 = t1.ToUpper();
            t22 = t12.ToUpper();

            if (!string.IsNullOrEmpty(withNameContaining.Value)  && !string.IsNullOrEmpty(withNameContaining2.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.ToUpper().Contains(t2) && g.name.ToUpper().Contains(t22)).ToList();
                    store.Values = taggedObjects.ToArray();
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.Contains(t1) && g.name.Contains(t12)).ToList();
                    store.Values = taggedObjects.ToArray();
                }

            }
        }

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

Code: [Select]
using UnityEngine;
using System.Linq;

#pragma warning disable 168

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

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t2;

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

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

        void Find ()
        {
            t1 = withTagContaining.Value;
            t2 = t1.ToUpper();

            if (!string.IsNullOrEmpty(withTagContaining.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.ToUpper().Contains(t2)).ToList();
                    store.Values = taggedObjects.ToArray();
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.Contains(t1)).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;
        }
    }
}

Code: [Select]
using UnityEngine;
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 an FSM Array.")]
    public class FindGameObjectsWithTagContaining2 : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Find any GameObject(s) with a Tag containing two Strings.  First this String...")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("And with the GameObject(s) having a Tag containing this string too.")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining2;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t12;
        private string t2;
        private string t22;

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

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

        void Find ()
        {
            t1 = withTagContaining.Value;
            t12 = withTagContaining2.Value;
            t2 = t1.ToUpper();
            t22 = t12.ToUpper();

            if (!string.IsNullOrEmpty(withTagContaining.Value)  && !string.IsNullOrEmpty(withTagContaining2.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.ToUpper().Contains(t2) && g.tag.ToUpper().Contains(t22)).ToList();
                    store.Values = taggedObjects.ToArray();
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.Contains(t1) && g.tag.Contains(t12)).ToList();
                    store.Values = taggedObjects.ToArray();
                }

            }
        }

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

Sorry will have to post the Counting actions below...

Enjoy!
« Last Edit: April 02, 2017, 06:06:54 AM by Duffer »

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #1 on: April 02, 2017, 06:05:52 AM »
And here are the 4 GO Search matching Count FSM Actions...

Code: [Select]
using UnityEngine;
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 the count of them in an FSM Int.")]
    public class CountGameObjectsWithNameContaining : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Find any GameObject(s) with a Name containing this string and Count the number of them.")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t2;

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

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

        void Find ()
        {
            t1 = withNameContaining.Value;
            t2 = t1.ToUpper();

            if (!string.IsNullOrEmpty(withNameContaining.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.ToUpper().Contains(t2)).ToList();
                    store.Value = taggedObjects.Count;
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.Contains(t1)).ToList();
                    store.Value = taggedObjects.Count;
                }

            }
        }

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

Code: [Select]
using UnityEngine;
using System.Linq;

#pragma warning disable 168

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory(ActionCategory.GameObject)]
    [Tooltip("Count any GameObject(s) with a Name that contains a particular String and stores the count of them in an FSM Int.")]
    public class CountGameObjectsWithNameContaining2 : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Count any GameObject(s) with a Name containing two Strings.  First this String...")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("And with the GameObject(s) having a Name containing this String too.")]
        [VariableType(VariableType.String)]
        public FsmString withNameContaining2;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t12;
        private string t2;
        private string t22;

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

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

        void Find ()
        {
            t1 = withNameContaining.Value;
            t12 = withNameContaining2.Value;
            t2 = t1.ToUpper();
            t22 = t12.ToUpper();

            if (!string.IsNullOrEmpty(withNameContaining.Value) && !string.IsNullOrEmpty(withNameContaining2.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.ToUpper().Contains(t2) && g.name.ToUpper().Contains(t22)).ToList();
                    store.Value = taggedObjects.Count;
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.name.Contains(t1) && g.name.Contains(t12)).ToList();
                    store.Value = taggedObjects.Count;
                }

            }
        }

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

Code: [Select]
using UnityEngine;
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 the count of them in an FSM Int.")]
    public class CountGameObjectsWithTagContaining : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Find any GameObject(s) with a Tag containing this string and Count the number of them.")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t2;

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

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

        void Find ()
        {
            t1 = withTagContaining.Value;
            t2 = t1.ToUpper();

            if (!string.IsNullOrEmpty(withTagContaining.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.ToUpper().Contains(t2)).ToList();
                    store.Value = taggedObjects.Count;
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.Contains(t1)).ToList();
                    store.Value = taggedObjects.Count;
                }

            }
        }

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

Code: [Select]
using UnityEngine;
using System.Linq;

#pragma warning disable 168

namespace HutongGames.PlayMaker.Actions
{
    [ActionCategory(ActionCategory.GameObject)]
    [Tooltip("Count any GameObject(s) with a Tag that contains a particular String and stores the count of them in an FSM Int.")]
    public class CountGameObjectsWithTagContaining2 : FsmStateAction
    {
        [UIHint(UIHint.Variable)]
        [Tooltip("Count any GameObject(s) with a Tag containing two Strings.  First this String...")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining;

        [UIHint(UIHint.Variable)]
        [Tooltip("And with the GameObject(s) having a Tag containing this String too.")]
        [VariableType(VariableType.String)]
        public FsmString withTagContaining2;

        [UIHint(UIHint.Variable)]
        [Tooltip("If this bool is set to True then the String search is case insensitive.")]
        [VariableType(VariableType.Bool)]
        public FsmBool caseInsensitive;

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

        private string t1;
        private string t12;
        private string t2;
        private string t22;

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

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

        void Find ()
        {
            t1 = withTagContaining.Value;
            t12 = withTagContaining2.Value;
            t2 = t1.ToUpper();
            t22 = t12.ToUpper();

            if (!string.IsNullOrEmpty(withTagContaining.Value) && !string.IsNullOrEmpty(withTagContaining2.Value))
            {
                if (caseInsensitive.Value == true)
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.ToUpper().Contains(t2) && g.tag.ToUpper().Contains(t22)).ToList();
                    store.Value = taggedObjects.Count;
                }
                else
                {
                    var taggedObjects = Resources.FindObjectsOfTypeAll(typeof(GameObject)).Cast<GameObject>().Where(g => g.tag.Contains(t1) && g.tag.Contains(t12)).ToList();
                    store.Value = taggedObjects.Count;
                }

            }
        }

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

Enjoy!

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #2 on: April 05, 2017, 01:59:00 AM »
Hi,

 great!! you should consider putting them on the Ecosystem, if you are ok with Github? I can give you access if you want.

 Bye,

 Jean

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #3 on: April 05, 2017, 02:07:38 AM »
Not really sure about github or how to do that?

Happy for someone to stick the actions on ecosystem for me?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #4 on: April 05, 2017, 02:11:07 AM »
Hi,

 ok, I'll put them up :)

 Bye,

 Jean

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #5 on: April 10, 2017, 04:01:43 AM »
Hi,

 I have put one up already, which is an improved version of your actions. the action is called: FindGameObjectsResourcesWithNameContaining


Few comments:

-- don't use useVariable attributes on inputs, only on outputs.
-. are you sure you want to access ANY GameObjects, using Resources.FindObjectsOfTypeAll means accessing even internal GameObject, it's dangerous, do you want to check only in the hierarchy or only within the Resources folder?

 -- also, I combine both actions by giving the ability to input several containing strings using the a list, then you don't need to duplicate actions just for this,

-- also, I let the developer also save the gameobjectts found, I am not sure giving just the number of object found is useful if you don't do anything with them.


 Bye,

 Jean

kavery

  • Full Member
  • ***
  • Posts: 149
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #6 on: November 27, 2019, 03:54:23 PM »
Is there a way to search only in the hierarchy?

Abelius

  • Junior Playmaker
  • **
  • Posts: 68
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #7 on: February 06, 2021, 08:57:07 AM »
Hi,

 I have put one up already, which is an improved version of your actions. the action is called: FindGameObjectsResourcesWithNameContaining

Thank you and the OP for this, but I'd have a request if I may.

Could you add another string variable, or string array, to add support for exceptions?

So we could search for all GOs starting with the name tf_Chair, but not tf_ChairL1, for example.

I've tried to do it myself, but I lack the knowledge to modify this action in particular.

Thanks.
Unity 2019.4.9f1
Playmaker 1.9.7f1

djaydino

  • Administrator
  • Hero Member
  • *****
  • Posts: 7615
    • jinxtergames
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #8 on: February 07, 2021, 10:38:54 AM »
Hi.
After the FindGameObjectsResourcesWithNameContaining
you could loop thru the array to refine what you need.

Maart

  • Junior Playmaker
  • **
  • Posts: 88
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #9 on: April 26, 2021, 10:17:00 AM »
could you please create an action that counts both?
objects with name containing AND has tag "x"?

Thanks