playMaker

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

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
    • View Profile
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, 03:06:54 AM by Duffer »

Duffer

  • Playmaker Newbie
  • *
  • Posts: 26
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #1 on: April 02, 2017, 03: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: 15069
  • Official Playmaker Support
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #2 on: April 04, 2017, 10:59:00 PM »
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
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #3 on: April 04, 2017, 11:07:38 PM »
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: 15069
  • Official Playmaker Support
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #4 on: April 04, 2017, 11:11:07 PM »
Hi,

 ok, I'll put them up :)

 Bye,

 Jean

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15069
  • Official Playmaker Support
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #5 on: April 10, 2017, 01: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: 123
    • View Profile
Re: Find GOs by Name (or Tag) which contains a particular String.
« Reply #6 on: November 27, 2019, 01:54:23 PM »
Is there a way to search only in the hierarchy?